Checkpoint web parity through Chromium input tasks
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Blender 5.2 全功能对标工作分解
|
||||
|
||||
更新时间:2026-08-15
|
||||
更新时间:2026-08-18
|
||||
|
||||
> 本文保留为 Blender 全产品覆盖检查表和 F00-F24 taxonomy 参考。M12-M23 的执行分类、
|
||||
> 原子任务、证据合同与发布门以 `BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` 为准;
|
||||
@@ -17,7 +17,7 @@ V1 盘点术语;完整对标结论必须按新计划转换为 `LOCAL_EXACT/LOC
|
||||
N-015 至 N-026 的 12 个 family 全部仍为 `parityStatus=BLOCKED`。因此以下任务默认均为未完成;
|
||||
只有 `docs/status/parity-ledger.json` 和对应专项证据同时更新后才允许改变状态。
|
||||
|
||||
短周期唯一领取顺序仍以 `docs/CURRENT_EXECUTION_PLAN.md` 为准。本文负责验证新计划没有遗漏
|
||||
短周期唯一领取顺序仍以 `docs/EXECUTION_QUEUE.md` 和对应任务卡为准。本文负责验证新计划没有遗漏
|
||||
产品域;与新计划冲突时按新计划解释,不取代当前执行队列或长期实施事实源。
|
||||
|
||||
## 2. 原子任务完成定义
|
||||
@@ -516,12 +516,39 @@ N-015 至 N-026 的 12 个 family 全部仍为 `parityStatus=BLOCKED`。因此
|
||||
|
||||
## 29. 当前领取点
|
||||
|
||||
截至 2026-08-17,M6-M11 已按当前计划完成,M11 最终以 Render、Compositor、Media 三域故障
|
||||
截至 2026-08-18,M6-M11 已按当前计划完成,M11 最终以 Render、Compositor、Media 三域故障
|
||||
生命周期专项门收口,M12-01A-I 已完成 catalog schema/migration;M12-02A-H 又完成 PreviewImage
|
||||
inventory、identity、decode budget、OPFS commit、dedupe、quarantine、project-scoped reference GC
|
||||
与 desktop/browser 双显示路径像素闭环。本文的 F00-F24
|
||||
条目只作为覆盖检查表,不能直接领取;M12-03A 又冻结 Append/Link/Override 的 36 类 root 与
|
||||
实际 ID pointer dependency closure;M12-03B 固定 source/owner/read-only/invalidation identity;
|
||||
M12-03C 冻结 Blender 5.2 单 Object append 的 Object/Mesh/Material/Image local stable mapping;
|
||||
M12-03D 已通过 WASM Main 单 transaction 创建同一 local dependency closure。当前唯一下一任务为
|
||||
`BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` 中的 `M12-03E`。
|
||||
M12-03D 已通过 WASM Main 单 transaction 创建同一 local dependency closure,M12-03E 又完成
|
||||
undo/redo/save/reopen 与 desktop canonical graph 的联合一致性,M12-03F 又冻结 desktop LINK
|
||||
source-library/read-only ownership,M12-03G 又完成 linked writer fail-closed gate,M12-03H 又完成
|
||||
matching-generation reload,M12-03I 又完成 missing-library placeholder/source preservation,M12-03J 又冻结
|
||||
desktop override reference/local-owner/property contract,M12-03K 又开放单一 verified override writer,
|
||||
M12-03L 又冻结 freshness gate,M12-03M/N 又收口 negative cases 与三 lane 独立命令矩阵。
|
||||
M12-04A-J 又冻结 declared source admission、canonical path、path/origin safety、link resolution、
|
||||
metadata-first、archive budget/conflict、cancellation rollback、quota/OOM recovery 与恶意 ZIP/TAR
|
||||
长期回归;M12-05A 又从 pinned Blender 5.2 runtime 生成七格式 operator/build inventory,M12-05C
|
||||
又将 M12-05B capability matrix SHA-256 绑定到文件选择器与 operator search,M12-05D 又将
|
||||
执行路由绑定到 14 条 runtime receipt,M12-05E 又固定每条 receipt 的 source/settings/runtime
|
||||
三重 hash,M12-05F 又增加 parent byte、canonical receipt-set 和 runtime identity freshness gate,
|
||||
并对未声明/未注册/未绑定/伪造/过期/跨版本组合保持 fail-closed;M12-06A 又由 pinned Blender
|
||||
5.2 desktop 生成五个独立 Mesh/PBR/UV/skin/animation GLB fixture,并完成逐字节确定性重生成;
|
||||
M12-06B 又让生产 Web parser 在 Node 与 Chromium Worker 中精确比较 topology、attributes、
|
||||
materials、nodes 和 animations;M12-06C 又完成 desktop GLB import 后的 Main save/reopen 与
|
||||
stable-ID 比较;M12-06D 又固定 Web export machine loss report;M12-06E 又完成 desktop Web GLB
|
||||
re-import canonical comparison;M12-06F 又固定 sparse/extension/URI/budget negative gate;
|
||||
M12-06G 又完成 GLB import/export 取消、Worker 换代和真实 OPFS quota 恢复;M12-07A 又冻结
|
||||
单 Mesh OBJ/MTL position/normal/UV/material-group desktop 正例;M12-07B 又冻结双对象、负索引、
|
||||
相对纹理来源和坏 face 负例;M12-07C 又完成 Web-to-desktop OBJ round-trip/loss report;
|
||||
M12-07D 又分开冻结 STL binary/ASCII capability;M12-07E 又完成 normal/unit/degenerate/trailing
|
||||
desktop/Web 对标并记录 stricter trailing block;M12-07F 又完成 STL Web-to-desktop round-trip/material
|
||||
loss report;M12-07G 又分开冻结 PLY ASCII/binary little-endian capability;M12-07H 又完成
|
||||
PLY vertex/face/color/custom property mapping 与 unknown-property loss report;M12-07I 又完成
|
||||
big-endian/坏 list/超大 count 稳定阻断;M12-07J 又完成 OBJ/STL/PLY 三格式 recovery;M13-01A 又完成脚本
|
||||
入口 inventory;M13-02A 又完成 bounded script manifest limits;M13-02B 又完成 canonical
|
||||
serialization signature input;M13-02C 又完成 signer identity/key rotation/revocation/timestamp policy;M13-02D-F 又完成签名、权限、sandbox scope/budget/host-call、crash/timeout、cancellation 和 dispose 资源归零门。当前唯一下一任务为
|
||||
`EXECUTION_QUEUE.md` 中的 `M13-04F`;具体上下文见 `docs/tasks/M13-04F.md`。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Blender 5.2 完整 Web 对标实施计划
|
||||
|
||||
更新时间:2026-08-17
|
||||
更新时间:2026-08-18
|
||||
|
||||
本文是 M12 及以后完整 Blender 5.2 Web 迁移的长期规范事实源,负责执行分类、原子任务、
|
||||
依赖、证据和完整发布门。它不覆盖 `WEB_BLENDER_MODELER_V1_SCOPE.md` 的 V1 产品契约,也不
|
||||
@@ -11,7 +11,7 @@
|
||||
| 事实 | 权威来源 |
|
||||
| --- | --- |
|
||||
| V1 承诺、非目标和发布标准 | `WEB_BLENDER_MODELER_V1_SCOPE.md` |
|
||||
| 当前唯一可领取任务 | `CURRENT_EXECUTION_PLAN.md` 与机器 `nextTask` |
|
||||
| 当前唯一可领取任务 | `EXECUTION_QUEUE.md`、对应 `tasks/<task>.md` 与机器 `nextTask` |
|
||||
| M12-M23 完整对标规则和长期任务 | 本文 |
|
||||
| 当前实现事实和 family/slice 状态 | `status/parity-ledger.json` 与对应 evidence |
|
||||
| Blender 全域功能说明和覆盖参考 | `BLENDER_5_2_WEB_FEATURE_PARITY.md`、`BLENDER_5_2_FULL_PARITY_WBS.md` |
|
||||
@@ -19,8 +19,36 @@
|
||||
描述与机器证据冲突时不得用文字把失败改成成功。M12-01A-I 已收口,M12-02A-G preview
|
||||
inventory/identity/decode budget/OPFS commit/dedupe/quarantine/GC 已完成且未改变 parity 状态;
|
||||
desktop/browser 主线程与 Offscreen preview 像素闭环也已完成;Append/Link/Override 数据块与
|
||||
依赖闭包 inventory、source/owner/read-only/invalidation 合同、desktop 单 Object append fixture
|
||||
及 WASM Main 单 transaction append 已完成,当前唯一 `nextTask` 为 `M12-03E`。
|
||||
依赖闭包 inventory、source/owner/read-only/invalidation 合同、desktop 单 Object append fixture、
|
||||
WASM Main 单 transaction append 及其 undo/redo/save/reopen canonical 比较已完成,desktop LINK
|
||||
fixture 也已冻结 source-library/read-only ownership,linked writer fail-closed gate、matching-generation
|
||||
reload、missing-library placeholder preservation、desktop override ownership/property fixture、单一
|
||||
verified override writer、freshness gate、三 lane 独立命令矩阵、declared source-origin admission、
|
||||
canonical project-path normalization、path/origin security、archive link/metadata/budget/conflict gate、
|
||||
cancellation rollback、quota/OOM recovery 与恶意 ZIP/TAR 长期回归已完成;M12-05A 已从 pinned
|
||||
Blender 5.2 runtime 生成 7-format inventory,M12-05B 已冻结逐格式 local/server capability matrix,
|
||||
M12-05C 已将 UI 文件选择与 operator search 绑定到该 matrix,M12-05D 又将执行路由绑定到
|
||||
M12-05A 的 Blender runtime receipt,M12-05E 又为 14 条 receipt 固定 source/settings/runtime 三重
|
||||
hash,M12-05F 又增加 parent byte、canonical receipt-set 和 runtime identity freshness gate;M12-06A
|
||||
又由 pinned Blender 5.2 desktop 生成 mesh、PBR、UV、skin、animation 五个独立 GLB fixture,并以
|
||||
逐字节重生成和 semantic report 固定 fixture group;M12-06B 又由 Node 与 Chromium Worker 对
|
||||
topology、attributes、materials、nodes、animations 做 exact canonical 比较;M12-06C 又完成桌面
|
||||
GLB 导入后的 authoritative Main 保存、重开、stable-ID 比较和 Chromium 资源释放门;M12-06D 又
|
||||
固定 Web export machine loss report;M12-06E 又完成 pinned Blender 对 Web GLB 的 save/reopen
|
||||
canonical comparison,并将 UV/skin 的明确差异保留为 machine mismatches;M12-06F 又固定
|
||||
sparse/extension/外部 URI/budget 负例;M12-06G 再完成双向取消、Worker 换代和真实 OPFS quota
|
||||
恢复;M12-07A 又由 pinned Blender 5.2 生成 OBJ 单 Mesh position/normal/UV/material-group
|
||||
正例并完成逐字节重生成;M12-07B 又冻结 OBJ 双对象、负索引、相对纹理来源和坏 face 负例;
|
||||
M12-07C 又完成 Web Worker OBJ/MTL 重写、纹理 loss report 和 Blender 5.2 重导入比较;
|
||||
M12-07D 又把同一 Blender Mesh 的 STL binary/ASCII runtime capability 分开冻结;M12-07E 又完成
|
||||
normal/unit/degenerate/trailing desktop/Chromium 对标并记录 trailing 的 stricter Web block;
|
||||
M12-07F 又完成 Web binary STL 重写、Blender 重导入和 material-loss report;M12-07G 又冻结
|
||||
Blender 5.2 的 PLY ASCII 与 binary little-endian 两个独立 capability variant;M12-07H 又完成
|
||||
PLY vertex/face/color/custom property 映射与未知 property loss report;M12-07I 又完成
|
||||
big-endian、坏 list、超大 count 的稳定阻断;M12-07J 又完成 OBJ/STL/PLY 三格式 recovery;M13-01A
|
||||
又完成脚本入口盘点;M13-01B 又完成 `.blend` 脚本 metadata-only open;M13-01C 又冻结默认拒绝
|
||||
policy codes;M13-01D 又通过 UI direct-eval bypass scan;M13-01E 又通过 Text save/reopen;M13-01F
|
||||
又通过恶意脚本 fixture;M13-02A 又通过 bounded script manifest limits;M13-02B 又固定 canonical serialization signature input;M13-02C 又完成 signer identity/key rotation/revocation/timestamp policy;M13-02D 又完成声明内容 ED25519 验签;M13-02E 又完成权限最小化;M13-02F 又完成签名负例矩阵;M13-03A 又冻结 all-deny sandbox scope;M13-03B 又冻结 CPU/wall/memory/message/output budgets;M13-03C 又冻结结构化 host-call allowlist;M13-03D 又冻结 crash/timeout isolation、Main revision 不变和迟到结果拒绝;M13-03E 又冻结 cancellation no-publish/cache gate;M13-03F 又冻结 Worker/两端 MessagePort/timer/AbortController/buffer/cache reference dispose gate;M13-03G 又冻结同会话 generation/revision/hash-chain recovery;M13-04A 又冻结随机 `0700` one-shot server job directory;M13-04B 又冻结 source/output 权限隔离;M13-04C 又冻结六类资源预算;M13-04D 又冻结默认拒绝网络策略;M13-04E 又冻结 pinned Blender background/factory-startup argv,当前唯一 `nextTask` 为 `M13-04F`。
|
||||
|
||||
## 1. 目标与边界
|
||||
|
||||
@@ -42,7 +70,9 @@ WebGPU 或 JavaScript 近似结果不能冒充 Blender 结果。
|
||||
和项目绑定,不允许只返回“应走服务端”。
|
||||
6. 完整项目通过保存、关闭、Worker/页面重启、重新打开和 Blender desktop 再打开;未知数据
|
||||
不丢失,不支持的写操作不污染原文件。
|
||||
7. Chromium、Firefox、WebKit 的支持声明分别由自己的 quick/P0/full 证据决定,不互相推断。
|
||||
7. 本项目浏览器执行、CI、验收证据和发布声明永久仅限 Chromium。Firefox 与 WebKit 禁止启动、
|
||||
探测、领取测试任务或生成支持证据;历史报告仅作归档背景。缺失 WebGPU 只能由 Chromium
|
||||
真实能力门将依赖 WebGPU 的功能标记为 `BLOCKED`,不得用其他浏览器推断。
|
||||
|
||||
Native window、CUDA/Metal/HIP/OptiX 实现细节不需要在浏览器复制,但它们提供的用户能力必须
|
||||
由 WebGPU、CPU 或 `SERVER_EXACT` 路径覆盖。若没有等价执行路径,就保持 `BLOCKED`,项目不得
|
||||
@@ -101,9 +131,18 @@ Native window、CUDA/Metal/HIP/OptiX 实现细节不需要在浏览器复制,
|
||||
## 2. 当前基线
|
||||
|
||||
- 当前交付物是可审计的 Chromium `Web Blender Modeler V1`,不是完整 Blender。
|
||||
- M6 至 M11 已完成;M12-01A-I、M12-02A-G enabling tasks 与 M12-02H preview display
|
||||
parity slice 及 M12-03A-D library-operation inventory/identity/desktop fixture/WASM Main append
|
||||
已完成,当前唯一下一任务为 M12-03E。
|
||||
- M6 至 M11 已完成;M12-01A-I、M12-02A-H、M12-03A-N、M12-04A-J、M12-05A inventory、
|
||||
M12-05B capability matrix、M12-05C UI gate、M12-05D runtime receipt gate、M12-05E receipt
|
||||
binding、M12-05F freshness gate、M12-06A desktop GLB fixture generation、M12-06B Web semantic import
|
||||
comparison、M12-06C Main save/reopen stable-ID slice、M12-06D Web machine loss report 和
|
||||
M12-06E desktop re-import comparison、M12-06F GLB negative-case budget gate 和 M12-06G
|
||||
cancellation/Worker restart/OPFS quota recovery、M12-07A OBJ single-Mesh desktop fixture 和
|
||||
M12-07B OBJ multi-object/negative/texture-origin fixture、M12-07C Web-to-desktop round-trip 和
|
||||
M12-07D split STL binary/ASCII capability、M12-07E normal/unit/edge parity、M12-07F
|
||||
Web-to-desktop round-trip/loss report、M12-07G PLY ASCII/binary little-endian capability 和
|
||||
M12-07H vertex/face/color/custom property mapping/loss report、M12-07I negative admission
|
||||
gate 和 M12-07J 三格式 recovery 已完成,M13-01A script entry inventory、M13-01B metadata-only open、
|
||||
M13-01C default-deny policy codes、M13-01D UI bypass scan、M13-01E Text save/reopen、M13-01F malicious fixture、M13-02A manifest limits、M13-02B canonical serialization、M13-02C signer trust policy、M13-02D declaration-bound signature verification、M13-02E permission minimization、M13-02F signature negative matrix、M13-03A sandbox scope、M13-03B sandbox budgets、M13-03C host-call allowlist、M13-03D crash/timeout isolation、M13-03E cancellation no-publish/cache gate、M13-03F dispose 资源归零、M13-03G 同会话恢复审计链、M13-04A one-shot server job directory、M13-04B source/output 权限隔离、M13-04C 六类资源预算、M13-04D 默认拒绝网络和 M13-04E Blender runtime argv 也已完成,当前唯一下一任务为 M13-04F。
|
||||
- N-015 至 N-026 的 V1 `releaseStatus` 为 `READY`,但 12 个 family 的全域
|
||||
`parityStatus` 仍全部为 `BLOCKED`。
|
||||
- 这 12 个 family 是当前 post-V1 账本范围,不覆盖完整 Blender inventory;不能把它们未来的
|
||||
@@ -189,8 +228,8 @@ commit、runtime 或 fixture 的局部成功。`parityStatus=VERIFIED` 必须由
|
||||
| OOM/quota/cancel/crash 后小任务恢复 | 必须 | 必须 | 浏览器与 server 两侧都必须 |
|
||||
| 真实 Blender server | 禁止作为本地成功替代 | 禁止作为等价外壳成功替代 | 必须 |
|
||||
|
||||
Firefox/WebKit 不在每个早期原子任务的默认完成门中;M14 声明某浏览器支持后,该浏览器对
|
||||
所有已验证 `parityId` 的适用 browser evidence 立即成为强制项,不能由 Chromium 结果代替。
|
||||
Firefox/WebKit 永久不在本项目的完成门、CI、支持声明或发布证据中;M14 只允许 Chromium
|
||||
设备/输入和 Chromium capability evidence。不得通过新增浏览器任务恢复这两个范围。
|
||||
|
||||
### 3.5 比较器
|
||||
|
||||
@@ -235,7 +274,7 @@ M12 至 M15 是当前确定队列。M16 至 M22 的具体领取顺序由 M15 生
|
||||
由一个专项命令串联。
|
||||
|
||||
本节已由 `npm --prefix web run test:render-compositor-media-recovery`、`M11-14` status、专项
|
||||
evidence 和 family ledger 联合收口。M12-03D 完成后,当前唯一 `nextTask` 为 `M12-03E`。
|
||||
evidence 和 family ledger 联合收口。M12-04I 完成后,当前唯一 `nextTask` 为 `M12-04J`。
|
||||
|
||||
## 6. M12 Asset、Library、IO 与 Editor
|
||||
|
||||
@@ -298,61 +337,127 @@ evidence 和 family ledger 联合收口。M12-03D 完成后,当前唯一 `next
|
||||
- [x] `M12-03D` WASM Main append 以一次 transaction 创建本地 owner 数据;Worker 先校验 source
|
||||
hash、closure 和 revision,Blender Main 递归导入 Object/Mesh/Material/packed Image,四个 ID
|
||||
均验证为可写 local owner,并只推进一个 SceneIR revision。
|
||||
- [ ] `M12-03E` append undo/redo/save/reopen 与 desktop canonical report 一致。
|
||||
- [ ] `M12-03F` desktop link fixture 保留 source library 和只读 ownership。
|
||||
- [ ] `M12-03G` linked data writer 全部返回 `LINKED_DATA_MUTATION_BLOCKED`。
|
||||
- [ ] `M12-03H` library reload 只替换匹配 generation 的 linked snapshot。
|
||||
- [ ] `M12-03I` missing library 保留 placeholder 和原始 source,不删除引用。
|
||||
- [ ] `M12-03J` desktop override fixture 记录 reference、local owner 和 property override path。
|
||||
- [ ] `M12-03K` 首个 override writer 只开放一个已验证属性。
|
||||
- [ ] `M12-03L` override stale source/revision 在 Main commit 前阻断。
|
||||
- [ ] `M12-03M` dependency cycle、ID collision、跨库环和重复 reload 负例。
|
||||
- [ ] `M12-03N` append/link/override 各有独立 desktop/WASM/Chromium 命令。
|
||||
- [x] `M12-03E` append undo/redo/save/reopen 与 desktop canonical report 一致;WASM Main 的
|
||||
append closure 在一次 transaction 后,undo 移除全部四个 ID,redo 与 save/reopen 均恢复
|
||||
desktop canonical graph(图像像素比较先做 Blender bottom-up row normalization;SceneIR 缺省的
|
||||
Image.colorSpace 使用 desktop sRGB semantic default,若字段出现则必须匹配)。
|
||||
- [x] `M12-03F` desktop link fixture 保留 source library 和只读 ownership;四个 linked ID 均
|
||||
保留 `m12_link_source.blend` library pointer、无 library override,并在 save/reopen 后保持
|
||||
`SOURCE_LIBRARY/readOnly=true` stable mapping。
|
||||
- [x] `M12-03G` linked data writer 全部返回 `LINKED_DATA_MUTATION_BLOCKED`;object transform、
|
||||
mesh geometry/material slot、material property/image node 和 packed image 六类 writer 在
|
||||
Main 前统一 fail-closed,stale revision 仍返回 `REVISION_CONFLICT`。
|
||||
- [x] `M12-03H` library reload 只替换匹配 generation 的 linked snapshot;stale generation/revision、
|
||||
source substitution、duplicate identity 和 non-adjacent replacement 均 fail-closed。
|
||||
- [x] `M12-03I` missing library 保留 `MISSING_LIBRARY` placeholder、原始 source locator/SHA、generation、
|
||||
revision 和 data-block IDs,不删除引用;stale/source drift 均 fail-closed。
|
||||
- [x] `M12-03J` desktop override fixture 记录 source reference、`LOCAL_OVERRIDE` owner、hierarchy root
|
||||
和唯一 property override path,并在 save/reopen 后保持稳定。
|
||||
- [x] `M12-03K` 首个 override writer 只开放 `["m12_override_value"]`,并保持 `LOCAL_OVERRIDE`/
|
||||
reference-read-only semantics;其它 property、owner、identity 和 value 均 fail-closed。
|
||||
- [x] `M12-03L` override stale source generation/revision、dependency closure、invalidation token 和
|
||||
identity 在 Main commit 前阻断;只有完整匹配返回 `READY`。
|
||||
- [x] `M12-03M` dependency cycle、ID collision、跨库环和重复 reload 负例均返回稳定阻断码。
|
||||
- [x] `M12-03N` append/link/override 各有独立 desktop/WASM/Chromium 命令,共 9 条实测入口。
|
||||
|
||||
### M12.4 Origin、路径与 archive
|
||||
|
||||
- [ ] `M12-04A` library source schema 只接受声明的 HTTPS origin、项目 asset 或用户选择文件。
|
||||
- [ ] `M12-04B` 规范化 POSIX/Windows separator、`.`、`..`、percent encoding 和 Unicode 名称。
|
||||
- [ ] `M12-04C` 拒绝绝对路径、UNC、drive path、NUL、控制字符和 origin 逃逸。
|
||||
- [ ] `M12-04D` 符号链接/hardlink entry 在写入前解析并限制在临时根。
|
||||
- [ ] `M12-04E` archive 先读取 central directory/manifest,不先解压 payload。
|
||||
- [ ] `M12-04F` 单 entry 字节、总字节、entry 数、目录深度和文件名长度预算。
|
||||
- [ ] `M12-04G` 压缩比、重叠 range、重复路径、文件/目录前缀冲突负例。
|
||||
- [ ] `M12-04H` 解压取消删除 staging,不修改已提交项目。
|
||||
- [ ] `M12-04I` quota/OOM 后释放临时文件并允许小 archive 恢复。
|
||||
- [ ] `M12-04J` 恶意 ZIP/TAR fixture 进入长期安全回归。
|
||||
- [x] `M12-04A` library source schema 只接受声明的 HTTPS origin、项目 asset 或用户选择文件;credential-bearing
|
||||
URL、undeclared origin、unsafe project path 和 malformed user-file identity 均 fail-closed。
|
||||
- [x] `M12-04B` 规范化 POSIX/Windows separator、`.`、`..`、percent encoding 和 Unicode 名称;canonical
|
||||
project paths are `/`-separated, NFC-normalized, percent-decoded once, and idempotent。
|
||||
- [x] `M12-04C` 拒绝绝对路径、UNC、drive path、NUL、控制字符和 origin 逃逸;HTTPS policy origin
|
||||
同样拒绝 path/query/fragment、编码控制和 backslash smuggling,不把不安全声明静默降成裸 origin。
|
||||
- [x] `M12-04D` 符号链接/hardlink entry 在写入前解析并限制在临时根。
|
||||
- [x] `M12-04E` archive 先读取 central directory/manifest,不先解压 payload。
|
||||
- [x] `M12-04F` 单 entry 字节、总字节、entry 数、目录深度和文件名长度预算。
|
||||
- [x] `M12-04G` 压缩比、重叠 range、重复路径、文件/目录前缀冲突负例。
|
||||
- [x] `M12-04H` 解压取消删除 staging,不修改已提交项目;真实临时目录验证零 staging、零发布与
|
||||
committed revision/SHA-256 不变,原子 commit 开始后不再伪报取消。
|
||||
- [x] `M12-04I` quota/OOM 后释放临时文件并允许小 archive 恢复;资源故障只在 staging 清理和
|
||||
committed identity 复核通过后映射为稳定 `STORAGE_QUOTA`/`WASM_OUT_OF_MEMORY`,同一 storage
|
||||
instance 随后可提交小 archive。
|
||||
- [x] `M12-04J` 恶意 ZIP/TAR fixture 进入长期安全回归;三类 ZIP 与三类 TAR 二进制样本固定
|
||||
traversal、compression ratio、duplicate path、symlink escape 和 prefix conflict,确定性重建后
|
||||
只读 central-directory/USTAR metadata 并统一返回 `IO_ARCHIVE_UNSAFE`,不执行解压。
|
||||
|
||||
### M12.5 格式 capability matrix
|
||||
|
||||
- [ ] `M12-05A` 从 Blender 5.2 build/runtime 生成 glTF/GLB、OBJ、STL、PLY、USD、Alembic 清单。
|
||||
- [ ] `M12-05B` 每种格式分别声明 import/export、local/server、geometry/material/animation 支持。
|
||||
- [ ] `M12-05C` matrix 未声明组合在文件选择器和 operator search 中不可执行。
|
||||
- [ ] `M12-05D` 能力由 runtime receipt 决定,不按扩展名推断。
|
||||
- [ ] `M12-05E` 每个 receipt 绑定 source/settings/runtime hash。
|
||||
- [ ] `M12-05F` 伪造、过期或跨版本 receipt 在使用前拒绝。
|
||||
- [x] `M12-05A` 从 pinned Blender 5.2 build/runtime 生成 GLTF/GLB、OBJ、STL、PLY、USD、Alembic
|
||||
清单;每条 receipt 绑定 operator RNA、build option、runtime metadata 与 binary SHA-256,USD/
|
||||
Alembic 在 disabled build 上明确 `OPERATOR_UNREGISTERED`。
|
||||
- [x] `M12-05B` 每种格式分别声明 import/export、local/server、geometry/material/animation 支持;
|
||||
只有已有 bounded GLB local export route 为 READY,其余 27 条 route 均显式 `BLOCKED`,未实现
|
||||
feature 保持 `UNVERIFIED`。
|
||||
- [x] `M12-05C` matrix 未声明组合在文件选择器和 operator search 中不可执行;UI registry 绑定
|
||||
M12-05B matrix SHA-256,只接受 `.blend` 项目并仅暴露已有 bounded GLB local export,阻断的
|
||||
import/export route 不进入 `accept` 或搜索结果,文件名 gate 在 Engine 前返回
|
||||
`IO_FORMAT_UNSUPPORTED`。
|
||||
- [x] `M12-05D` 能力由 runtime receipt 决定,不按扩展名推断;14 条 M12-05A import/export
|
||||
receipt 绑定 pinned Blender 5.2 inventory SHA-256,App 的 format-tagged operator 与 GLB
|
||||
export 在执行前都要求 receipt=`AVAILABLE`、operator registered、RNA identity 存在且 build
|
||||
option 未禁用,USD/Alembic `OPERATOR_UNREGISTERED` 保持 `IO_FORMAT_UNSUPPORTED`。
|
||||
- [x] `M12-05E` 每个 receipt 绑定 source/settings/runtime hash;14 条 receipt 同时绑定 M12-05D
|
||||
receipt-set SHA-256 和 M12-05A inventory SHA-256,source/operator、canonical settings/RNA
|
||||
properties、Blender runtime identity 三个 hash 在使用前均要求存在且格式正确。
|
||||
- [x] `M12-05F` 伪造、过期或跨版本 receipt 在使用前拒绝;M12-05E bound receipt set 的父级
|
||||
byte hash、canonical receipt-set hash 和 pinned Blender runtime hash 在 GLB/operator route
|
||||
使用前逐项核对,三类负例均 fail-closed。
|
||||
|
||||
### M12.6 GLB round-trip
|
||||
|
||||
- [ ] `M12-06A` desktop 生成 Mesh/PBR/UV/skin/animation GLB fixture 组。
|
||||
- [ ] `M12-06B` Web import 比较 topology、attributes、materials、nodes 和 animations。
|
||||
- [ ] `M12-06C` import 后保存 `.blend`、重开并比较 stable ID。
|
||||
- [ ] `M12-06D` Web export 生成 machine loss report。
|
||||
- [ ] `M12-06E` desktop Blender 再导入 Web GLB 并比较 canonical report。
|
||||
- [ ] `M12-06F` sparse accessor、Draco/extension、外部 URI 和超预算负例。
|
||||
- [ ] `M12-06G` import/export 取消、Worker restart 和 OPFS quota 恢复。
|
||||
- [x] `M12-06A` pinned Blender 5.2 desktop 生成五个独立 Mesh/PBR/UV/skin/animation GLB fixture;
|
||||
每个文件均无 extension、在 512 KiB 单文件预算内,manifest 绑定 runtime、generator、report
|
||||
和五个 GLB SHA-256,独立临时目录二次生成逐字节一致。
|
||||
- [x] `M12-06B` Web import 比较 topology、attributes、materials、nodes 和 animations;生产
|
||||
TypeScript parser、Node unit 与 Chromium Worker 对五个 desktop fixture 做 exact canonical hash
|
||||
和字段级比较,GLB file-picker route 在 Main persistence 完成前继续阻断。
|
||||
- [x] `M12-06C` desktop GLB import 后生成 authoritative Main `.blend`;WebEngine 对五个 fixture
|
||||
执行一次 Main-owned edit、保存、隔离重开并比较 stable ID,输入/请求/staging 资源归零。
|
||||
- [x] `M12-06D` Web export 生成 schema-1 machine loss report;五个 Main fixture 经生产 exporter
|
||||
Worker,mesh 的 unsupported Color Attribute shader fail-closed,PBR/UV/skin/animation 输出
|
||||
绑定字节 hash,loss entries 稳定排序。
|
||||
- [x] `M12-06E` pinned Blender 5.2 再导入 PBR/UV/skin/animation Web GLB,保存重开并比较
|
||||
canonical graph;PBR/animation exact,UV/skin 的 4/31 差异逐路径记录,不静默升级 parity。
|
||||
- [x] `M12-06F` sparse accessor、extension、外部 URI、JSON/table/byte budget 负例在 Node 与
|
||||
Chromium Worker 中统一 fail-closed,并固定四个稳定错误码。
|
||||
- [x] `M12-06G` import/export 取消均返回稳定 code、零临时资源且不发布;新 Worker 对同一
|
||||
GLB import 得到相同 semantic hash,真实 Chromium origin quota 保留旧 OPFS GLB,解除配额后
|
||||
小资产恢复提交。
|
||||
|
||||
### M12.7 OBJ、STL、PLY round-trip
|
||||
|
||||
- [ ] `M12-07A` OBJ 单 Mesh 正例:position/normal/UV/material group。
|
||||
- [ ] `M12-07B` OBJ 多对象、负索引、MTL/texture origin 和坏 face 负例。
|
||||
- [ ] `M12-07C` OBJ Web→desktop round-trip 与 loss report。
|
||||
- [ ] `M12-07D` STL binary/ASCII capability 分开声明。
|
||||
- [ ] `M12-07E` STL normal、unit、degenerate triangle 和 trailing bytes 对标。
|
||||
- [ ] `M12-07F` STL Web→desktop round-trip 与材质缺失 loss report。
|
||||
- [ ] `M12-07G` PLY ASCII/binary little-endian capability 分开声明。
|
||||
- [ ] `M12-07H` PLY vertex/face/color/custom property 映射与未知 property loss report。
|
||||
- [ ] `M12-07I` PLY big-endian/坏 list/超大 count 稳定阻断。
|
||||
- [ ] `M12-07J` 三格式分别执行取消、OOM、重启和小文件恢复。
|
||||
- [x] `M12-07A` pinned Blender 5.2 `wm.obj_export` 生成单 Mesh OBJ/MTL 正例;四个 position、
|
||||
四个 UV、一个 normal、两个 triangle face、两个 material 和两个 material group 的 canonical
|
||||
report 在新临时目录逐字节重生成一致。
|
||||
- [x] `M12-07B` pinned Blender 5.2 生成双对象 OBJ/MTL/PNG 正例,并从同一正例派生负索引和
|
||||
两顶点坏 face;canonical report 固定相对 `map_Kd` origin、2 objects/2 faces/2 materials,
|
||||
负例分别为 `ACCEPT_WITH_NEGATIVE_INDICES` 与 `OBJ_FACE_ARITY_INVALID`,新目录重生成逐字节一致。
|
||||
- [x] `M12-07C` bounded Web OBJ parser/serializer 在 Chromium Worker 读取 M12-07B fixture,绑定
|
||||
texture 时 loss 为 0、缺失 texture 时返回两个稳定 warning;Web OBJ/MTL 写入临时目录后由
|
||||
pinned Blender 5.2 `wm.obj_import` 重开,2 objects/2 triangles/UVMap/material 逐项一致。
|
||||
- [x] `M12-07C` OBJ Web→desktop round-trip 与 loss report。
|
||||
- [x] `M12-07D` pinned Blender 5.2 `wm.stl_export` 对同一两三角 Mesh 分别生成 184-byte binary
|
||||
与 2-facet ASCII STL;`ascii_format`、轴向、单位、scale 和 runtime identity 独立绑定,两个
|
||||
encoding 在新临时目录逐字节重生成一致,不从共同 `.stl` 扩展名推断 variant。
|
||||
- [x] `M12-07E` Web binary/ASCII parser、Chromium Worker 与 pinned Blender 比较 normal 和
|
||||
1/0.001 unit scale;双方均移除一个 degenerate triangle 并保留另一个。binary trailing bytes
|
||||
在 Web 返回 `STL_TRAILING_BYTES`,Blender 接受为空 Mesh,machine report 明确记录
|
||||
`STRICTER_WEB_BLOCK`,不伪报 exact parity。
|
||||
- [x] `M12-07F` Web Worker 将 bounded STL binary 重写后交给 pinned Blender 5.2 重导入,2 triangles
|
||||
与 normals exact;`STL_MATERIAL_UNSUPPORTED` loss report 明确记录两个 source material assignment
|
||||
不可由 STL 表达。
|
||||
- [x] `M12-07G` pinned Blender 5.2 `wm.ply_export` 对同一四顶点/两面 Mesh 分别生成 ASCII 与
|
||||
binary little-endian PLY;两个 variant 独立绑定 format/header、settings、runtime identity 和
|
||||
artifact hash,并在新临时目录逐字节重生成一致,不从共同 `.ply` 扩展名推断 encoding。
|
||||
- [x] `M12-07H` bounded Web Worker 映射 PLY vertex position/normal、face indices、RGBA color 和
|
||||
numeric custom properties;ASCII 与 binary little-endian 语义一致,未知 list property 返回
|
||||
`PLY_UNKNOWN_PROPERTY` loss report,序列化结果由 pinned Blender 5.2 重导入验证。
|
||||
- [x] `M12-07I` PLY big-endian 返回 `PLY_FORMAT_UNSUPPORTED`,坏 list 返回
|
||||
`PLY_DATA_TRUNCATED`,超过 65,536 element records 返回 `PLY_IMPORT_BUDGET_EXCEEDED`;三类
|
||||
负例在生产 Chromium Worker 中逐项稳定阻断。
|
||||
- [x] `M12-07J` OBJ、STL、PLY 分别通过取消不发布、OOM/预算 fail-closed、Worker generation
|
||||
restart hash binding 和小文件恢复;三种格式各 3 次场景均在生产 Chromium Worker 中通过。
|
||||
|
||||
### M12.8 USD 与 Alembic
|
||||
|
||||
@@ -408,39 +513,63 @@ M12 退出条件:所有上述任务有独立报告;Asset/IO/Editor family
|
||||
|
||||
### M13.1 默认拒绝与只读盘点
|
||||
|
||||
- [ ] `M13-01A` 盘点 Text、Python Console、autorun、driver expression、handler 和 add-on 入口。
|
||||
- [ ] `M13-01B` `.blend` 打开时只读取脚本 metadata,不执行任意内容。
|
||||
- [ ] `M13-01C` autorun、register、install、driver execution 默认返回稳定 policy code。
|
||||
- [x] `M13-01A` pinned Blender 5.2 盘点 Text、Python Console、autorun、driver expression、
|
||||
handler 和 add-on 入口;报告固定 3 Text、3 Console operator、1 autorun request、1 driver、
|
||||
39 handler groups、4 add-on operators,并把 Web policy 固定为 metadata-only/deny。
|
||||
- [x] `M13-01B` `.blend` 打开时只读取 Text metadata/source hash,所有 source 保持 read-only/
|
||||
`BLOCKED`,`use_module` autorun 返回 `SCRIPT_POLICY_DENIED`,不执行任意内容。
|
||||
- [x] `M13-01C` autorun/register/install/driver execution 默认返回稳定
|
||||
`SCRIPT_POLICY_DENIED`、`DRIVER_EXECUTION_BLOCKED`、`ADDON_INSTALL_BLOCKED`;批准签名仍因
|
||||
缺 sandbox 返回 `SCRIPT_SANDBOX_UNAVAILABLE`。
|
||||
- [x] `M13-01D` 生产 app/Worker/protocol 176 个 TypeScript 文件无 `eval(` 或 `new Function(`;
|
||||
UI 只消费声明的 policy entry points,不提供直接 eval 入口。
|
||||
- [x] `M13-01E` `script_scene.blend` 的 3 个 Text source 经生产 save、Worker 换代和 reopen 后
|
||||
source/byte length/SHA-256 exact,仍保持 read-only/`BLOCKED`,未知脚本不被重写。
|
||||
- [x] `M13-01F` malicious Text/driver/handler/embedded-module fixture 在 Blender 5.2 生成并由
|
||||
Chromium 打开验证,4 个 source 全部 read-only/`BLOCKED`,embedded module 返回
|
||||
`SCRIPT_POLICY_DENIED`。
|
||||
- [ ] `M13-01D` UI 不提供绕过协议直接 eval 的入口。
|
||||
- [ ] `M13-01E` 保存/重开保留原 Text 数据块和未知脚本,不重写源码。
|
||||
- [ ] `M13-01F` malicious text、driver、handler 和 embedded module fixture 进入负例。
|
||||
|
||||
### M13.2 Script manifest 与签名
|
||||
|
||||
- [ ] `M13-02A` manifest 限制文本数量、总字节、module、path、dependency 和 permission。
|
||||
- [ ] `M13-02B` canonical serialization 固定签名输入。
|
||||
- [ ] `M13-02C` 定义 signer identity、key rotation、revocation 和 timestamp policy。
|
||||
- [ ] `M13-02D` signature 只批准声明内容,source hash 变化立即失效。
|
||||
- [ ] `M13-02E` permission 默认最小化,未知 permission 阻断。
|
||||
- [ ] `M13-02F` replay、key confusion、过期、撤销和多签顺序负例。
|
||||
- [x] `M13-02A` manifest 限制文本数量、总字节、module、path、dependency 和 permission;每个脚本声明
|
||||
`sourceByteLength`/`module=false`,总源码字节、脚本/依赖/权限数量和项目内 canonical path 均由
|
||||
production parser fail-closed 校验,并有 Node/Chromium 正负例与 artifact-bound report。
|
||||
- [x] `M13-02B` canonical serialization 固定签名输入;生产协议导出唯一 canonicalize/serialize
|
||||
入口,按 locale-independent code-unit 排序 script/permission/dependency,移除未知字段并固定
|
||||
canonical JSON;Node/Chromium order-invariance、security-field mutation 和 schema rejection 均通过。
|
||||
- [x] `M13-02C` 定义 signer identity、key rotation、revocation 和 timestamp policy;版本化
|
||||
trust policy 绑定 ED25519 public key、publisher、active/revoked、validity/revocation timestamp、
|
||||
same-publisher acyclic rotation chain 与 bounded clock skew,resolver 只返回
|
||||
`cryptographicVerification=REQUIRED` 的后续验签资格,不启用脚本。
|
||||
- [x] `M13-02D` signature 只批准 canonical 声明内容;ED25519 验签成功,source hash 或 signature 变化返回 `SCRIPT_SIGNATURE_INVALID`,revoked key 返回 `SCRIPT_POLICY_DENIED`。
|
||||
- [x] `M13-02E` permission 默认最小化;无显式请求时授予空集,只有 manifest 已声明且请求的 permission 才能授予,未知/重复/未声明请求返回 `SCRIPT_POLICY_DENIED`。
|
||||
- [x] `M13-02F` replay、key confusion、过期、not-yet-valid、publisher mismatch 和跨脚本 signature swap 负例稳定阻断;不新增执行入口。
|
||||
- [x] `M13-02F` replay、key confusion、过期、撤销和多签顺序负例。
|
||||
|
||||
### M13.3 浏览器 sandbox
|
||||
|
||||
- [ ] `M13-03A` sandbox scope 不暴露 DOM、主 Worker、OPFS、IndexedDB 或网络。
|
||||
- [ ] `M13-03B` CPU、wall time、memory、message 和 output byte budget 固定。
|
||||
- [ ] `M13-03C` host call 使用显式 allowlist 和结构化参数。
|
||||
- [ ] `M13-03D` sandbox crash/timeout 终止当前 job,不污染 Main revision。
|
||||
- [ ] `M13-03E` cancellation 后不得发布迟到 message 或 cache。
|
||||
- [ ] `M13-03F` dispose 后 Worker、port、timer 和 buffer 归零。
|
||||
- [ ] `M13-03G` 小脚本在同会话恢复,审计链保持连续。
|
||||
- [x] `M13-03A` sandbox scope 不暴露 DOM、主 Worker、OPFS、IndexedDB 或网络;scope schema 对五项能力逐项要求 `false`,执行仍为 `DISABLED`。
|
||||
- [x] `M13-03B` sandbox 固定 CPU、wall-time、memory、message 和 output-byte budgets;五项超限均返回 `SCRIPT_BUDGET_EXCEEDED`,执行仍为 `DISABLED`。
|
||||
- [x] `M13-03C` host call 仅允许 `READ_MAIN`、`READ_ASSET`、`WRITE_MAIN`、`WRITE_ASSET`、`SUBMIT_SERVER_JOB`,调用权限与 manifest 声明绑定,参数结构和项目路径严格校验,解析结果仍为 `execution=DISABLED`。
|
||||
- [x] `M13-03C` host call 使用显式 allowlist 和结构化参数。
|
||||
- [x] `M13-03D` sandbox crash/timeout 终止当前 job,不污染 Main revision;真实 Chromium Worker crash/timeout 均无发布结果,Main revision 保持不变,迟到结果返回 `SCRIPT_SANDBOX_LATE_RESULT`。
|
||||
- [x] `M13-03E` cancellation receipt 绑定 job/generation/base revision;取消后的 message、host-call
|
||||
result 和 cache write 均在 publish 前被 gate,真实 Chromium 迟到窗口 `lateMessages=0/cacheWrites=0`。
|
||||
- [x] `M13-03F` dispose 后 Worker、两端 MessagePort、timer、AbortController、transferable buffer、
|
||||
pending request 和 cache reference 逐项归零;重复 dispose 幂等,迟到 timer message 为 0。
|
||||
- [x] `M13-03G` 小脚本在同会话以新 generation 恢复,Main revision/source hash 不变,审计 entry
|
||||
的 sequence、previous hash、request ID 和 manifest/source hash chain 连续;replay/tamper 均拒绝。
|
||||
|
||||
### M13.4 Blender server job isolation
|
||||
|
||||
- [ ] `M13-04A` 每个 job 创建不可预测的一次性目录。
|
||||
- [ ] `M13-04B` source 只读挂载,output 写独立目录。
|
||||
- [ ] `M13-04C` CPU、内存、进程、文件、时间和 output budget 由 OS/container 强制。
|
||||
- [ ] `M13-04D` 默认无网络;声明 origin 使用单独 policy。
|
||||
- [ ] `M13-04E` Blender 只以 background/factory-startup 和固定 startup script 启动。
|
||||
- [x] `M13-04A` 每个 job 创建不可预测的 `0700` 一次性目录,request ID 不进入目录名,清理无残留且幂等。
|
||||
- [x] `M13-04B` source 只读挂载(目录/文件 `0555/0444`),output 写独立目录(`0700`),真实 source write 返回 `EACCES`。
|
||||
- [x] `M13-04C` 固定 CPU、内存、进程、文件、wall-time 和 output budget;六类超限稳定返回 `SERVER_JOB_BUDGET_EXCEEDED`,OS/container 实际强制留给后续真实 process 证据。
|
||||
- [x] `M13-04D` 默认无网络;声明 origin 使用单独 policy,missing/undeclared/unsafe origin 稳定拒绝。
|
||||
- [x] `M13-04E` Blender 只以 background/factory-startup 和固定 startup script 启动,pinned 5.2.0 runtime receipt 通过。
|
||||
- [ ] `M13-04F` stdout/stderr 截断并过滤凭据/绝对内部路径。
|
||||
- [ ] `M13-04G` cancel 终止 Blender process tree 并清理临时目录。
|
||||
- [ ] `M13-04H` timeout/OOM/exit signal 转换为稳定错误码。
|
||||
@@ -449,12 +578,12 @@ M12 退出条件:所有上述任务有独立报告;Asset/IO/Editor family
|
||||
|
||||
### M13.5 CSP、供应链与恶意输入
|
||||
|
||||
- [ ] `M13-05A` CSP 禁止 inline script、eval、data script 和未声明 origin。
|
||||
- [ ] `M13-05B` Worker、WASM、font、image、media 的 CSP 分别验证。
|
||||
- [ ] `M13-05C` 生产依赖、构建依赖、测试依赖分别生成 inventory。
|
||||
- [ ] `M13-05D` severity 门和例外包含 owner、期限、理由和替代控制。
|
||||
- [ ] `M13-05E` SBOM、license、source offer 与 archive/commit hash 绑定。
|
||||
- [ ] `M13-05F` malicious blend/image/font/media/archive/node graph/manifest 全矩阵。
|
||||
- [x] `M13-05A` CSP 禁止 inline script、eval、data script 和未声明 origin。
|
||||
- [x] `M13-05B` Worker、WASM、font、image、media 的 CSP 分别验证。
|
||||
- [x] `M13-05C` 生产依赖、构建依赖、测试依赖分别生成 inventory。
|
||||
- [x] `M13-05D` severity 门和例外包含 owner、期限、理由和替代控制。
|
||||
- [x] `M13-05E` SBOM、license、source offer 与 archive/commit hash 绑定。
|
||||
- [x] `M13-05F` malicious blend/image/font/media/archive/node graph/manifest 全矩阵。
|
||||
- [ ] `M13-05G` fuzz crash 先保存最小样本,再修复,再进入长期回归。
|
||||
- [ ] `M13-05H` audit record 使用严格时间顺序、request ID 和防篡改 hash chain。
|
||||
|
||||
@@ -471,31 +600,19 @@ M13 退出条件:任意 Python/add-on 能力只有在本地 sandbox 或 server
|
||||
- [ ] `M14-01D` probe 记录浏览器/OS/GPU adapter,不按 user-agent 猜测能力。
|
||||
- [ ] `M14-01E` 缺 WebGPU 只阻断依赖 WebGPU 的功能,不影响可验证 WebGL2/Main。
|
||||
|
||||
### M14.2 Firefox
|
||||
### M14.2 Firefox(永久跳过)
|
||||
|
||||
- [ ] `M14-02A` Firefox quick:type/protocol/static asset 启动。
|
||||
- [ ] `M14-02B` Firefox P0:open/edit/undo/redo/save/reopen/export。
|
||||
- [ ] `M14-02C` Firefox 主线程 WebGL2 像素和 context loss。
|
||||
- [ ] `M14-02D` Firefox Offscreen 只在主线程通过后领取。
|
||||
- [ ] `M14-02E` Firefox OPFS quota、Worker crash、OOM 和 network interruption。
|
||||
- [ ] `M14-02F` Firefox full family 命令逐项 PASS/BLOCKED,禁止静默 fallback。
|
||||
- [ ] `M14-02G` Firefox quick/P0/full 进入 CI 后才更新支持声明。
|
||||
- [x] `M14-02A`-`M14-02G` 永久跳过:Chromium-only 铁律。
|
||||
|
||||
### M14.3 WebKit
|
||||
### M14.3 WebKit(永久跳过)
|
||||
|
||||
- [ ] `M14-03A` WebKit quick 启动和本地 asset 完整性。
|
||||
- [ ] `M14-03B` WebKit P0 用户闭环。
|
||||
- [ ] `M14-03C` WebKit 主线程 viewport。
|
||||
- [ ] `M14-03D` WebKit Offscreen 独立 gate。
|
||||
- [ ] `M14-03E` WebKit storage/fault/recovery。
|
||||
- [ ] `M14-03F` WebKit full family matrix。
|
||||
- [ ] `M14-03G` WebKit CI 和发布说明。
|
||||
- [x] `M14-03A`-`M14-03G` 永久跳过:Chromium-only 铁律。
|
||||
|
||||
### M14.4 设备档位与输入
|
||||
|
||||
- [ ] `M14-04A` GPU/内存预算按声明设备档位选择,不自动扩容。
|
||||
- [ ] `M14-04B` DPR 1/1.5/2/3 下 canvas、raycast、gizmo 和截图一致。
|
||||
- [ ] `M14-04C` pointer mouse、touch、pen 分开记录 pressure/tilt/button/cancel。
|
||||
- [x] `M14-04A` GPU/内存预算按声明设备档位选择,不自动扩容。
|
||||
- [x] `M14-04B` DPR 1/1.5/2/3 下 canvas、raycast、gizmo 和截图一致。
|
||||
- [x] `M14-04C` pointer mouse、touch、pen 分开记录 pressure/tilt/button/cancel。
|
||||
- [ ] `M14-04D` IME composition 不触发未完成 operator。
|
||||
- [ ] `M14-04E` US、非 US、dead key 和 modifier keymap fixture。
|
||||
- [ ] `M14-04F` 触控 modal cancel、双指导航和笔 stroke 只提交一次 Main transaction。
|
||||
@@ -606,10 +723,11 @@ M13 退出条件:任意 Python/add-on 能力只有在本地 sandbox 或 server
|
||||
## 12. 每轮执行规则
|
||||
|
||||
1. 从机器队列领取唯一 `nextTask`。
|
||||
2. 先运行现有正例,确认不是在旧失败上继续扩展。
|
||||
3. 写 fixture/golden 时实际启动锁定 Blender 5.2,不手工填写运行结果。
|
||||
4. 先完成协议和 fail-closed,再接 Main writer,再接浏览器 UI。
|
||||
5. 失败结果记录到工作日志,但不写成成功 evidence。
|
||||
6. 代码完成后运行专项;专项通过后运行全量 Node、typecheck、lint、build、status/evidence。
|
||||
7. 更新 ledger 时只增加本轮真实完成的 slice;family 全域状态保持 `BLOCKED` 直到 gap 为零。
|
||||
8. 每轮保留下一任务的可执行入口,不提前实现无依赖保证的后续功能。
|
||||
2. 浏览器测试只允许 Chromium;Firefox/WebKit 任务一律跳过,不得启动、探测或生成证据。
|
||||
3. 先运行现有正例,确认不是在旧失败上继续扩展。
|
||||
4. 写 fixture/golden 时实际启动锁定 Blender 5.2,不手工填写运行结果。
|
||||
5. 先完成协议和 fail-closed,再接 Main writer,再接浏览器 UI。
|
||||
6. 失败结果记录到工作日志,但不写成成功 evidence。
|
||||
7. 代码完成后运行专项;专项通过后运行全量 Node、typecheck、lint、build、status/evidence。
|
||||
8. 更新 ledger 时只增加本轮真实完成的 slice;family 全域状态保持 `BLOCKED` 直到 gap 为零。
|
||||
9. 每轮保留下一任务的可执行入口,不提前实现无依赖保证的后续功能。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Web Blender V1 当前执行计划
|
||||
|
||||
更新时间:2026-08-17
|
||||
更新时间:2026-08-19
|
||||
|
||||
## 1. 交付目标
|
||||
|
||||
@@ -18,7 +18,8 @@ React 工作区和编辑器
|
||||
-> OPFS 大文件 + IndexedDB 元数据
|
||||
```
|
||||
|
||||
本计划是当前唯一的短周期领取队列。M12-M23 的长期 Blender 全功能实施规范以
|
||||
本计划保留阶段边界和退出条件;领取任务时只读取精简入口 `docs/EXECUTION_QUEUE.md`、对应
|
||||
`docs/tasks/<task>.md` 和 parent manifest,避免加载历史日志。M12-M23 的长期 Blender 全功能实施规范以
|
||||
`BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` 为准;当前实现状态仍由
|
||||
`status/parity-ledger.json` 和对应 evidence 给出。长期全域差距不阻断已明确限定范围的 V1。
|
||||
|
||||
@@ -27,7 +28,7 @@ React 工作区和编辑器
|
||||
| 文件 | 唯一职责 |
|
||||
| --- | --- |
|
||||
| `WEB_BLENDER_MODELER_V1_SCOPE.md` | V1 产品契约、支持矩阵、非目标、发布标准 |
|
||||
| `CURRENT_EXECUTION_PLAN.md` | 当前任务顺序、最小任务、依赖和退出条件 |
|
||||
| `EXECUTION_QUEUE.md` + `tasks/<task>.md` | 当前唯一任务、最小上下文、依赖和验收入口 |
|
||||
| `PROJECT_STATUS_AND_NEXT_WORK.md` | 已实现能力、风险、验证命令总览 |
|
||||
| `BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` | M12-M23 完整 Web 对标的长期规范事实源 |
|
||||
| `BLENDER_5_2_WEB_FEATURE_PARITY.md` | Blender 5.2 功能域说明和当前差距参考 |
|
||||
@@ -107,7 +108,7 @@ React 工作区和编辑器
|
||||
| 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 missing;49/49 唯一 acceptance 通过 | 无 V1 证据缺口 | release gate 与 acceptance 审计链已闭环 |
|
||||
| 浏览器 | Chromium 主线程/Offscreen 两条路径 | Firefox、WebKit 未纳入 | Chromium-only |
|
||||
| 浏览器 | 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 已收口 |
|
||||
|
||||
@@ -159,9 +160,9 @@ loss、恶意 blend、zip bomb、离线包和 V1 用户闭环均已在最终 M5
|
||||
| M9 非 Mesh/GP/Paint | 字体、Curve、Grease Pencil、Paint 增量闭环 | 已完成,14/14 | 每个新增 writer 独立通过 Main/undo/save/golden;三域故障恢复闭环通过 |
|
||||
| M10 GN/Shader/NLA/Simulation | 白名单求值、cache、编译与阻断 | 已完成,15/15 | 四域分别通过 desktop/WASM/fault 门 |
|
||||
| M11 Render/Compositor/Media | 灯光、渲染、合成、媒体执行边界 | 已完成,14/14 | 本地白名单、server 边界与三域故障恢复均可审计 |
|
||||
| M12 Asset/IO/Editors | 资产、格式、编辑器和上下文工作流 | 进行中,M12-01A-I、M12-02A-H 与 M12-03A-D 完成 | 每个格式/editor 有独立 round-trip 或稳定阻断 |
|
||||
| M13 Scripting/Security | 脚本默认拒绝、服务端隔离、CSP、供应链 | 未开始 | 恶意输入矩阵和 release 安全门通过 |
|
||||
| M14 跨浏览器/设备 | Firefox、WebKit、触控、笔、HiDPI、IME | 未开始 | 新浏览器进入 quick/P0/full CI 后才声明支持 |
|
||||
| M12 Asset/IO/Editors | 资产、格式、编辑器和上下文工作流 | 进行中,M12-01A-I、M12-02A-H、M12-03A-N、M12-04A-J、M12-05A-F、M12-06A-G 与 M12-07A-J 完成 | 每个格式/editor 有独立 round-trip 或稳定阻断 |
|
||||
| M13 Scripting/Security | 脚本默认拒绝、服务端隔离、CSP、供应链 | 进行中,M13-01A-F、M13-02A-F、M13-03A-G、M13-04A-E 完成,当前 `M13-04F` | Text/Console/autorun/driver/handler/add-on inventory、`.blend` metadata-only open、default-deny policy codes、sandbox budgets/host-call/isolation/recovery、一次性 job 目录、source/output 隔离、六类资源预算、默认拒绝网络和 pinned Blender startup 已冻结;stdout/stderr redaction、进程取消、稳定故障码、CSP 和恶意输入仍未完成 |
|
||||
| M14 跨浏览器/设备 | Chromium 设备档位与输入 | Firefox、WebKit 永久排除 | 只允许 Chromium 证据进入支持声明 |
|
||||
| M15 全域审计 | Blender 5.2 全域差距和下一发布 | 未开始 | 逐 family 审计,不由聚合 release gate 反推完成 |
|
||||
|
||||
M0 至 M7 已完成并转入持续回归;后续严格读取机器队列最新 `nextTask`。里程碑内部允许先写
|
||||
@@ -828,9 +829,9 @@ CI 可从 lockfile 和对应源码重现当前 binary/source hash。
|
||||
|
||||
### M12 Asset、IO、Editor 与工作流
|
||||
|
||||
本节 M12-M15 仅保留短周期计划形成时的里程碑摘要,不再作为原子任务定义。M12-03D
|
||||
机器证据完成后,唯一下一任务为 `BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` 中的
|
||||
`M12-03E`;后续只能领取该文档或机器差距生成器给出的精确字母任务,不得领取下列整行摘要。
|
||||
本节 M12-M15 仅保留短周期计划形成时的里程碑摘要,不再作为原子任务定义。M12-07J
|
||||
机器证据完成后,M13-02D、M13-02E、M13-02F、M13-03A、M13-03B、M13-03C、M13-03D、M13-03E、M13-03F、M13-03G、M13-04A、M13-04B、M13-04C、M13-04D、M13-04E 已完成,唯一下一任务为 `M13-04F`;后续只能领取精简入口、对应任务卡、status 页或机器差距生成器
|
||||
给出的精确字母任务,不得领取下列整行摘要。
|
||||
|
||||
- [ ] `M12-01` asset catalog schema migration 有向前/向后兼容 fixture。
|
||||
- [ ] `M12-02` append/link/override 分别定义 stable ID、所有权和失效语义。
|
||||
@@ -865,10 +866,10 @@ CI 可从 lockfile 和对应源码重现当前 binary/source 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 流程采用相同规则。
|
||||
- [x] `M14-02` Firefox capability probe:永久跳过(Chromium-only 铁律)。
|
||||
- [x] `M14-03` Firefox P0 流程:永久跳过(Chromium-only 铁律)。
|
||||
- [x] `M14-04` Firefox 主线程/Offscreen:永久跳过(Chromium-only 铁律)。
|
||||
- [x] `M14-05` WebKit capability probe 和 P0 流程:永久跳过(Chromium-only 铁律)。
|
||||
- [ ] `M14-06` WebKit 主线程视口先通过,再领取 Offscreen 路径。
|
||||
- [ ] `M14-07` 浏览器不支持 WebGPU 时只隐藏明确依赖 WebGPU 的能力。
|
||||
- [ ] `M14-08` 内存上限按浏览器/设备档位选择已声明预算,不自动扩大。
|
||||
|
||||
54
docs/EXECUTION_QUEUE.md
Normal file
54
docs/EXECUTION_QUEUE.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Web Blender 短周期执行入口
|
||||
|
||||
更新时间:2026-08-19(America/New_York)
|
||||
|
||||
本页只负责“现在领取什么”。文档地图见 [`docs/README.md`](README.md),任务卡见 [`tasks/`](tasks/),
|
||||
长期规则见 `BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md`。不要在本页复制实现日志或历史任务表。
|
||||
|
||||
## 铁律:浏览器范围
|
||||
|
||||
本项目浏览器执行、CI、验收证据和发布声明永久仅限 Chromium。禁止启动、探测或领取 Firefox
|
||||
和 WebKit 测试任务;历史 Firefox/WebKit 报告仅作归档背景,不得作为支持证据。缺失 WebGPU
|
||||
只能由 Chromium 真实能力门将依赖 WebGPU 的功能标记为 `BLOCKED`,不得用其他浏览器推断。
|
||||
|
||||
## 当前指针
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 里程碑 | M14 跨浏览器/设备 |
|
||||
| 当前任务 | `M14-04F` |
|
||||
| parent manifest | `tests/golden/M14-04E/manifest.json` |
|
||||
| 任务卡 | [`tasks/M14-04F.md`](tasks/M14-04F.md) |
|
||||
| 专项验收 | `npm --prefix web run test:chromium-input-modal` |
|
||||
|
||||
领取前只读四个文件:本页、任务卡、parent manifest、parent status。完成后新增 task manifest/status,
|
||||
从新 manifest 的 `nextTask` 继续;Markdown 中的旧编号不覆盖机器指针。
|
||||
|
||||
## 任务链
|
||||
|
||||
| ID | 唯一交付 | 任务卡 |
|
||||
| --- | --- | --- |
|
||||
| M13-04F | stdout/stderr 有界截断与脱敏 | [`M13-04F.md`](tasks/M13-04F.md) |
|
||||
| M13-04G | 取消进程树并清理目录 | [`M13-04G.md`](tasks/M13-04G.md) |
|
||||
| M13-04H | timeout/OOM/signal 稳定错误码 | [`M13-04H.md`](tasks/M13-04H.md) |
|
||||
| M13-04I | hash 校验后原子提交 OPFS | [`M13-04I.md`](tasks/M13-04I.md) |
|
||||
| M13-04J | request 重试幂等和冲突隔离 | [`M13-04J.md`](tasks/M13-04J.md) |
|
||||
| M13-05G | fuzz 崩溃最小化与回归固化 | [`M13-05G.md`](tasks/M13-05G.md) |
|
||||
| M13-05H | 审计记录严格顺序与防篡改 hash chain | [`M13-05H.md`](tasks/M13-05H.md) |
|
||||
| M14-01A | 冻结 Chromium、engine 与 archive 身份 | [`M14-01A.md`](tasks/M14-01A.md) |
|
||||
| M14-01B | Firefox capability probe | 跳过:Chromium-only 铁律 |
|
||||
| M14-01C | WebKit capability probe | 跳过:Chromium-only 铁律 |
|
||||
| M14-01D | probe identity and GPU/OS adapter recording | [`M14-01D.md`](tasks/M14-01D.md) |
|
||||
| M14-01E | Chromium WebGPU fail-closed boundary | [`M14-01E.md`](tasks/M14-01E.md) |
|
||||
| M14-04A | Chromium GPU/memory budget device tier selection | [`M14-04A.md`](tasks/M14-04A.md) |
|
||||
| M14-04B | Chromium DPR 1/1.5/2/3 consistency | [`M14-04B.md`](tasks/M14-04B.md) |
|
||||
| M14-04C | Chromium mouse/touch/pen pointer contract | [`M14-04C.md`](tasks/M14-04C.md) |
|
||||
| M14-04D | Chromium IME composition guard | [`M14-04D.md`](tasks/M14-04D.md) |
|
||||
| M14-04E | Chromium US/non-US/dead-key/modifier keymap fixture | [`M14-04E.md`](tasks/M14-04E.md) |
|
||||
| M14-04F | Chromium touch modal cancel / two-finger / pen commit | [`M14-04F.md`](tasks/M14-04F.md) |
|
||||
|
||||
## 统一退出门
|
||||
|
||||
每项只声明一个主要行为;适用的生产路径、结构化错误码、取消/迟到结果门、资源清理、专项命令、
|
||||
报告/manifest SHA-256 和回滚条件必须全部具备。执行未通过、环境缺失或 hash 漂移时标记 `blocked`,
|
||||
不能用协议或测试文件存在替代真实运行结果。M13 脚本执行在本链完成前保持 `execution=DISABLED`。
|
||||
@@ -1,9 +1,9 @@
|
||||
# Web Blender 项目现状与后续连续任务
|
||||
|
||||
更新时间:2026-08-17
|
||||
更新时间:2026-08-19
|
||||
|
||||
当前短周期任务、领取顺序和阶段退出条件统一维护在
|
||||
`docs/CURRENT_EXECUTION_PLAN.md`。本文件保留实现事实、长期能力台账和完整验收命令,不再作为
|
||||
`docs/EXECUTION_QUEUE.md`。本文件保留实现事实、长期能力台账和完整验收命令,不再作为
|
||||
V1 的逐项领取顺序;V1 范围以 `docs/WEB_BLENDER_MODELER_V1_SCOPE.md` 为准,M12-M23 全功能
|
||||
实施规则以 `docs/BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` 为准。
|
||||
|
||||
@@ -38,13 +38,13 @@ SQLite WASM 和 Bitbybit/OCCT 均不在当前依赖范围内。Three.js、WASM
|
||||
| M9 非 Mesh/GP/Paint | 14/14 原子任务 | 0 | `TOGGLE_CYCLIC` 已通过 Main/undo/save/reopen 与 Blender 5.2 golden;GP current-drawing marquee、2D/3D 共享 selection revision 及 layer/frame reorder 已通过 Main/undo/save/reopen 门;Paint 主线程/Offscreen 真实 GPU depth、单 undo 分块 pointer session、normalize/limit/mirror 权重与 Blender 5.2 golden、packed/UDIM dirty tile 原子资产绑定,以及 46 项 PBVH brush 的 WASM 入口显式阻断已通过;Curve、Grease Pencil、Paint 三域的 Worker restart、OOM、GPU release、小场景恢复已通过;PBVH/桌面 brush 求值仍 BLOCKED |
|
||||
| M10 GN/Shader/NLA/Simulation | 15/15 原子任务 | 0 | GN/Simulation cache、Shader、NLA 和 Physics 有界闭环全部完成;M10-15 以四个隔离 Chromium Worker 分别通过性能、超预算/OOM-prevention、恶意输入和同会话小输入恢复门 |
|
||||
| M11 Lighting/Render/Compositor/Media | 14/14 原子任务 | 0 | M11-01/02 已冻结字段 parity 并完成支持字段闭环;M11-03 已让双 viewport 共用资源预算;M11-04 已完成 Blender Eevee reference 图像指标;M11-05/06 已完成最终渲染路由/provenance;M11-07/08 已完成有限 Compositor golden 与 Unsupported 全图阻断;M11-09/10/11/12 已完成 codec/proxy/revision/export gate;M11-13 已完成实时 AudioContext 恢复门;M11-14 已完成 Render/Compositor/Media 三域取消、重启、预算、释放和恢复门 |
|
||||
| M12 Asset/IO/Editors | M12-01A-I + M12-02A-H + M12-03A-D 共 21 项 | Append undo/redo/save/reopen、Link/Override 与后续 IO/Editor 仍未完成 | WASM Main 已有单 transaction append slice,但 N-023 全域 parity 仍阻断 |
|
||||
| M12 Asset/IO/Editors | M12-01A-I + M12-02A-H + M12-03A-N + M12-04A-J + M12-05A-F + M12-06A-G + M12-07A-J 共 64 项 | 后续 IO/Editor 仍未完成 | Archive 安全组、pinned Blender 5.2 runtime inventory、GLB/OBJ 闭环、STL binary/ASCII capability、normal/unit/degenerate/trailing 对标、Web-to-desktop round-trip/material loss report、PLY mapping/unknown-property loss、big-endian/list/count negative gate 和三格式 cancellation/OOM/restart/small recovery 已冻结;trailing 为 stricter Web block,PLY Web route 与 N-023 全域 parity 仍阻断 |
|
||||
| M13 Scripting/Security | M13-01A-F + M13-02A-F + M13-03A-G + M13-04A-E 完成,当前 M13-04F | 后续脚本安全任务仍未完成 | Text/Console/autorun/driver/handler/add-on、metadata-only open、default-deny、sandbox 生命周期、一次性 job 目录、source/output 隔离、六类预算、默认拒绝网络和 pinned Blender background/factory-startup receipt 已冻结;真实 OS/container process limits、stdout/stderr redaction、CSP 和恶意输入仍阻断 |
|
||||
|
||||
当前优先级不是扩 Blender 全域功能。single/pthread、真实 HTTP、缓存升级、离线闭环、
|
||||
独立归档复验、运维 runbook、RC 文档和最终三条 CI lane 均已通过;M7 核心项目体验硬化
|
||||
18/18 已完成并进入持续回归;M9 已完成 14/14;M10 已完成 15/15 并进入持续回归;M11 已完成
|
||||
14/14;M12-01A-I、M12-02A-H 和 M12-03A-D 已完成,机器队列的当前唯一 `nextTask` 为完整对标计划中的
|
||||
`M12-03E`。
|
||||
14/14;M12-01A-I、M12-02A-H、M12-03A-N、M12-04A-J、M12-05A-F、M12-06A-G 和 M12-07A-J 已完成,M13-04A-E 也已完成,机器队列的当前唯一 `nextTask` 为 `M13-04F`。
|
||||
|
||||
## 2. 已完成并有测试覆盖的能力
|
||||
|
||||
|
||||
43
docs/README.md
Normal file
43
docs/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# 文档导航
|
||||
|
||||
本目录按“产品契约、当前任务、实现事实、长期规划、验收证据”分层。领取任务时不要从仓库根目录
|
||||
开始通读;只读取当前队列、当前任务卡和机器 manifest 指向的状态页。
|
||||
|
||||
## 领取任务
|
||||
|
||||
1. [EXECUTION_QUEUE.md](EXECUTION_QUEUE.md):唯一的短周期入口,给出当前 `nextTask` 和读取顺序。
|
||||
2. `tasks/<task>.md`:当前任务的最小上下文、范围和验收命令。
|
||||
3. `tests/golden/<task>/manifest.json`:机器事实源,确认 parent、输入构件和下一个任务。
|
||||
4. `status/<task>.md`:完成后写入证据、hash、状态和回滚方式。
|
||||
|
||||
需要拆分实施或控制上下文时,先看 [TASK_BREAKDOWN.md](TASK_BREAKDOWN.md)。它提供阶段地图、
|
||||
原子任务门、当前 M14-04F 的子任务和后续任务草案,但不覆盖 manifest/status 的机器事实。
|
||||
|
||||
任务卡使用 [TASK_CONTEXT_TEMPLATE.md](TASK_CONTEXT_TEMPLATE.md) 的固定结构;卡片只描述一个主要
|
||||
行为或一个证据变化,不复制实现日志。
|
||||
|
||||
## 事实源
|
||||
|
||||
| 问题 | 文件 |
|
||||
| --- | --- |
|
||||
| V1 承诺、非目标、发布门 | [WEB_BLENDER_MODELER_V1_SCOPE.md](WEB_BLENDER_MODELER_V1_SCOPE.md) |
|
||||
| 当前领取顺序 | [EXECUTION_QUEUE.md](EXECUTION_QUEUE.md) + 当前 manifest 的 `nextTask` |
|
||||
| 当前实现和风险 | [PROJECT_STATUS_AND_NEXT_WORK.md](PROJECT_STATUS_AND_NEXT_WORK.md) |
|
||||
| M12-M23 长期原子计划 | [BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md](BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md) |
|
||||
| 机器状态和发布证据 | `status/parity-ledger.json`、`status/release-evidence.json` |
|
||||
| Blender 全域覆盖参考 | `BLENDER_5_2_WEB_FEATURE_PARITY.md`、`BLENDER_5_2_FULL_PARITY_WBS.md` |
|
||||
|
||||
## 其他文档
|
||||
|
||||
- `web/`:部署、CI、依赖、协议和已知限制等稳定合同。
|
||||
- `status/`:每个已完成或阻断任务的证据记录,不作为下一任务的唯一上下文。
|
||||
- `tasks/`:当前及近期任务卡;完成后保留,便于审计和回滚。
|
||||
- 根目录路线图和 `后续工作.txt`:历史设计与决策背景,不参与当前任务领取。
|
||||
|
||||
## 最小上下文规则
|
||||
|
||||
默认只加载本页列出的四个入口文件;实现细节按任务卡的文件清单追加读取。不要为了确认一个
|
||||
局部输入、IO 或安全任务而加载整份 `PROJECT_STATUS_AND_NEXT_WORK.md` 或完整 parity 计划。
|
||||
|
||||
文档描述与 manifest/evidence 冲突时,以可复验的机器状态为准;不要通过修改 Markdown
|
||||
checkbox 覆盖失败证据。
|
||||
208
docs/TASK_BREAKDOWN.md
Normal file
208
docs/TASK_BREAKDOWN.md
Normal file
@@ -0,0 +1,208 @@
|
||||
# 项目任务分解与最小上下文指南
|
||||
|
||||
更新时间:2026-08-19(America/New_York)
|
||||
|
||||
本文件是“如何拆任务、如何领取任务、如何交接”的规划索引,不是实现状态事实源。当前状态仍以
|
||||
`docs/EXECUTION_QUEUE.md`、当前任务的 `manifest.json`、对应 `docs/status/<task>.md` 和可复验命令为准。
|
||||
本文件的目标是让一次任务只加载必要上下文,不要求阅读整份路线图或历史接续日志。
|
||||
|
||||
## 1. 30 秒入口
|
||||
|
||||
每轮只按下面顺序读取:
|
||||
|
||||
1. `docs/EXECUTION_QUEUE.md`:确认唯一当前 `nextTask`、Chromium-only 规则和专项命令。
|
||||
2. `docs/tasks/<task>.md`:读取目标、输入、范围、验收和回滚。
|
||||
3. `tests/golden/<parent>/manifest.json`:确认 parent hash、依赖、运行时和下一任务。
|
||||
4. `docs/status/<parent>.md`:只读取上一项的证据摘要和已知风险。
|
||||
|
||||
只有遇到以下问题才继续读取:
|
||||
|
||||
| 问题 | 追加读取 |
|
||||
| --- | --- |
|
||||
| 不确定产品是否承诺 | `WEB_BLENDER_MODELER_V1_SCOPE.md` |
|
||||
| 不确定实现事实或已有命令 | `PROJECT_STATUS_AND_NEXT_WORK.md` 的相关小节 |
|
||||
| 不确定长期依赖或全域差距 | `BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` 的对应 M/F 小节 |
|
||||
| 不确定 family 状态 | `status/parity-ledger.json` 和 `release-evidence.json` |
|
||||
| 不确定协议字段 | 任务卡列出的 `web/protocol/*` 文件,不扫描整个 `web/` |
|
||||
|
||||
不要把 `README.md`、`后续工作.txt`、完整路线图和全部 status 日志作为每轮默认上下文。
|
||||
根目录路线图与历史接续记录仅用于背景;它们不能覆盖机器 manifest 的指针。
|
||||
|
||||
## 2. 文档职责和冲突处理
|
||||
|
||||
| 层级 | 唯一职责 | 可以回答 | 不能回答 |
|
||||
| --- | --- | --- | --- |
|
||||
| 产品契约 | `WEB_BLENDER_MODELER_V1_SCOPE.md` | V1 承诺、非目标、发布门 | 当前领取哪一项 |
|
||||
| 短周期入口 | `EXECUTION_QUEUE.md` | 当前任务、parent、专项命令 | 实现是否真的通过 |
|
||||
| 任务卡 | `tasks/<task>.md` | 单项范围、最小输入、验收、回滚 | 历史实现日志 |
|
||||
| 机器事实 | `tests/golden/*/manifest.json`、`status/*.json` | hash、依赖、运行时、状态轴 | 人类意图 |
|
||||
| 完成证据 | `status/<task>.md` | 实际命令、退出码、报告、风险 | 下一任务的推导顺序 |
|
||||
| 长期规划 | `BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md` | M12-M23/F 域规划 | 当前队列指针 |
|
||||
| 覆盖参考 | `BLENDER_5_2_FULL_PARITY_WBS.md` | Blender 全域检查表 | 独立完成证明 |
|
||||
|
||||
冲突时使用以下优先级:
|
||||
|
||||
```text
|
||||
可复验命令输出 > manifest/evidence > 当前任务卡 > 执行队列描述 > 长期规划/历史日志
|
||||
```
|
||||
|
||||
如果 manifest、status 和命令互相矛盾,先标记 `blocked`,不要修改 checkbox 或手工推进
|
||||
`nextTask`。
|
||||
|
||||
## 3. 原子任务规则
|
||||
|
||||
一个任务只能有一个主要行为变化,或一个独立证据变化。把“实现、浏览器接线、发布证据”混在一项
|
||||
会导致上下文过大,也会让测试文件存在被误判成生产能力完成。
|
||||
|
||||
每项任务都要能回答以下六个问题:
|
||||
|
||||
| 字段 | 最小内容 |
|
||||
| --- | --- |
|
||||
| 输入 | parent manifest、一个最小 fixture、生产入口 |
|
||||
| 行为 | 一个可观察的状态/数据/错误变化 |
|
||||
| 边界 | 至少一个非法、取消、超限或重复事件 |
|
||||
| 产物 | 一个协议/实现改动 + 一个 focused test/checker |
|
||||
| 验收 | 一条首选命令,必要时追加 typecheck/build |
|
||||
| 交接 | report、manifest、status、下一任务、回滚点 |
|
||||
|
||||
### 3.1 建议的子任务门
|
||||
|
||||
复杂能力按以下门拆开,每个门都可独立复验:
|
||||
|
||||
| 门 | 交付内容 | 常见文件 |
|
||||
| --- | --- | --- |
|
||||
| C 契约 | schema、稳定 ID、预算、错误码、revision 规则 | `web/protocol/*` |
|
||||
| P 生产路径 | Main/Worker/App/viewport 真正消费契约 | `web/app/src/*`、`web/engine/*` |
|
||||
| N 负例 | 非法、重复、取消、迟到、超限不改已提交状态 | `web/tests/unit/*` |
|
||||
| B 浏览器 | Chromium 真实用户路径和可见状态 | `tools/web/check-*.mjs`、`web/tests/e2e/*` |
|
||||
| R 资源 | dispose、取消、Worker 重启、OPFS/ GPU 预算归零 | Worker、storage、viewport |
|
||||
| E 证据 | 报告、SHA-256、manifest、status、回滚 | `tests/golden/*`、`docs/status/*` |
|
||||
|
||||
任务卡可以把 C/P/N/B/R/E 写成子任务,但只有所有适用门通过后,主任务才可变为 `done`。
|
||||
|
||||
## 4. 项目阶段分解
|
||||
|
||||
下面是导航级分解;具体领取仍由短周期队列决定。
|
||||
|
||||
| 阶段 | 主题 | 交付边界 | 当前使用方式 |
|
||||
| --- | --- | --- | --- |
|
||||
| M0 | 范围与状态模型 | V1 契约、双轴 ledger、P0 用户闭环 | 已完成,持续回归 |
|
||||
| M1 | 工作区收口 | 静态门、VDB 基线、P0 一致性 | 已完成,持续回归 |
|
||||
| M2 | 大几何 | 10M geometry、LOD、取消、释放、恢复 | 已完成,持续回归 |
|
||||
| M3 | 长媒体 | 索引、seek、取消、缓存、重开 | 已完成,持续回归 |
|
||||
| M4 | OOM/fault | WASM、OPFS、GPU、VDB 确定性恢复 | 已完成,持续回归 |
|
||||
| M5-M6 | V1/可部署 RC | 离线包、SBOM、CI、部署、升级、回滚 | 已完成,持续回归 |
|
||||
| M7 | 核心体验 | action/dirty/save/restart/recent projects/input 基础 | 已完成,持续回归 |
|
||||
| M8 | VDB 自动分页 | range/OPFS/LRU/双视口/device loss | 已完成,持续回归 |
|
||||
| M9 | 非 Mesh/GP/Paint | 有界 reader/writer、Main、保存重开、故障 | 已完成的 V1 slice;全域仍可能 BLOCKED |
|
||||
| M10 | GN/Shader/NLA/Simulation | allowlist、compile/cache、错误与恢复 | 已完成的 V1 slice;完整 evaluator 仍排除 |
|
||||
| M11 | Render/Compositor/Media | bounded local、server route、codec/revision/audio | 已完成的 V1 slice |
|
||||
| M12 | Asset/IO/Editors | 资产库、GLB/OBJ/STL/PLY、编辑器上下文 | 按 manifest 继续领取,不能按总百分比判断 |
|
||||
| M13 | Scripting/Security | metadata-only、default-deny、sandbox、server isolation、CSP | 每个安全门独立验收;execution 默认禁用 |
|
||||
| M14 | Chromium 设备与输入 | capability、预算、DPR、pointer、IME、keymap、modal、可访问性 | 当前短周期在 `M14-04F` |
|
||||
| M15 | 全域审计 | Blender 5.2 inventory、operator/node/editor/format gap | 未开始;不阻断已限定 V1 |
|
||||
|
||||
状态轴必须分开:V1 `releaseStatus=READY` 不等于 Blender 全域 `parityStatus=COMPLETE`。
|
||||
|
||||
## 5. 当前 M14-04F 细分
|
||||
|
||||
### 5.1 当前已知上下文
|
||||
|
||||
- parent:`M14-04E`,状态页已记录 keymap fixture 的成功证据。
|
||||
- 当前任务:`M14-04F`,任务卡为 `docs/tasks/M14-04F.md`。
|
||||
- 协议:`web/protocol/input-modal.ts`。
|
||||
- 单测:`web/tests/unit/input-modal.test.mjs`。
|
||||
- Chromium 检查器:`tools/web/check-chromium-input-modal.mjs`。
|
||||
- 报告/manifest:`tests/golden/M14-04F/`。
|
||||
- focused command:`npm --prefix web run test:chromium-input-modal`。
|
||||
|
||||
当前命令已经能证明协议单测通过,并能在 Chromium 页面派发 touch/pen 事件;完成主任务前还要
|
||||
确认事件确实进入生产输入状态和 Main transaction,而不是只在 checker 内构造事件并写入固定
|
||||
保证值。
|
||||
|
||||
### 5.2 子任务清单
|
||||
|
||||
| 子任务 | 唯一目标 | 最小改动面 | 必须证明 |
|
||||
| --- | --- | --- | --- |
|
||||
| F-C | 冻结 `InputModalState` schema 和状态转移 | `web/protocol/input-modal.ts` | pointer ID 非法时稳定拒绝;状态转移确定 |
|
||||
| F-T | 触控 modal 取消 | protocol + 生产 pointer cancel 入口 | cancel 后 `kind=NONE`、无 Main commit、活动 pointer 清零 |
|
||||
| F-2T | 双指导航 session 去重 | protocol + navigation dispatch | 从 1 到 2 个 pointer 只增加一次 `navigationRevision`;重复 down 不增加 |
|
||||
| F-P | 笔 stroke 单次提交 | protocol + pen pointerup/cancel 入口 | 第一个合法 up 最多一个 Main commit;late up/cancel 无二次提交 |
|
||||
| F-W | 主线程/Offscreen 生产接线 | App、viewport、Worker 输入边界 | 两条生产视口消费同一状态规则;cancel/late result 不污染 revision |
|
||||
| F-B | Chromium 真实断言 | checker/e2e + 最小 fixture | 读取 DOM/诊断/Main revision 的真实结果,而不是只检查派发数量 |
|
||||
| F-E | 证据和交接 | report、manifest、status | 命令退出 0、artifact hash 非空、风险/回滚清楚 |
|
||||
|
||||
### 5.3 完成门
|
||||
|
||||
主任务只有同时满足以下条件才可标记 `done`:
|
||||
|
||||
1. `F-C`、`F-T`、`F-2T`、`F-P` 的 Node 单测通过。
|
||||
2. `F-W` 在生产 App/viewport 中有实际 import 和事件消费路径。
|
||||
3. `F-B` 对至少 touch cancel、双指 session、pen late-up/cancel 做真实正负例断言。
|
||||
4. 取消或重复事件不产生迟到 Main commit,且 revision/commit counter 可观测。
|
||||
5. focused Chromium 命令、必要的 `typecheck`/`build` 和 `git diff --check` 通过。
|
||||
6. `docs/status/M14-04F.md`、`tests/golden/M14-04F/manifest.json` 和代码 hash 一致。
|
||||
|
||||
如果只有协议和测试通过,状态应保持 `in_progress`,不得提前领取 M14-04G。
|
||||
|
||||
## 6. M14 后续任务草案
|
||||
|
||||
这些是领取前的拆分草案;正式任务仍须由 parent manifest 生成任务卡。
|
||||
|
||||
### M14-04G:响应式布局无重叠/溢出
|
||||
|
||||
- 输入:M14-04F manifest、App shell、viewport CSS、四档 Chromium viewport。
|
||||
- 正例:`1440x900`、`1280x720`、`834x1112`、`390x844`。
|
||||
- 检查:`scrollWidth <= clientWidth`;topbar/sidebar/viewport/timeline/status 不互相覆盖;文字不被裁切;触控目标仍可操作。
|
||||
- 负例:窄视口、长项目名、错误提示、打开进度、面板展开、DPR 2。
|
||||
- 产物:布局 checker、4 档报告、截图或 bounding-box 摘要、manifest、status。
|
||||
- 不做:Firefox/WebKit;完整响应式重设计;新增 Blender 功能。
|
||||
|
||||
### M14-04H:键盘无障碍与焦点恢复
|
||||
|
||||
- 输入:M14-04G manifest、现有菜单/操作搜索/文件对话入口。
|
||||
- 正例:Tab 顺序、Escape 关闭 modal、Enter 提交、焦点回到触发器、按钮有 name/role。
|
||||
- 负例:modal 打开时快捷键穿透、焦点丢失、隐藏元素进入 tab 顺序、IME 期间提交 operator。
|
||||
- 产物:Chromium keyboard-only checker、焦点轨迹报告、必要的 ARIA/DOM 修复、manifest/status。
|
||||
- 不做:screen reader 的浏览器兼容性声明;Firefox/WebKit 证据。
|
||||
|
||||
### M15-01A 至 M15-01F:全域清单审计
|
||||
|
||||
1. 从 Blender 5.2 RNA 生成 data-block inventory。
|
||||
2. 生成 operator、poll context 和 property inventory。
|
||||
3. 生成 modifier、constraint、shader/GN/compositor node inventory。
|
||||
4. 生成 sequencer、physics、import/export inventory。
|
||||
5. 生成 editor/space/region/workspace/keymap inventory。
|
||||
6. 将 inventory ID 映射到 `parity-ledger.json`,拒绝未分类新增项并固定总 hash。
|
||||
|
||||
每一项都只产出一个稳定 inventory 或映射证据;不要在 M15 直接实现功能。
|
||||
|
||||
## 7. 交接格式
|
||||
|
||||
完成任务后,status 页只保留可审计摘要:
|
||||
|
||||
```text
|
||||
status: done | blocked
|
||||
task: <ID>
|
||||
updated: <timezone>
|
||||
scope: 一句话行为变化
|
||||
evidence: 命令、退出码、关键结果
|
||||
artifacts: report/manifest/代码 SHA-256
|
||||
nextTask: 仅复制 manifest.nextTask
|
||||
knownRisk: 仍未覆盖的边界
|
||||
rollback: 删除本任务产物并恢复 parent 队列尾
|
||||
```
|
||||
|
||||
不要把完整终端日志、实现过程或下一阶段设想复制进 status 页;长日志留在构件目录,任务卡只留
|
||||
最小输入和验收入口。
|
||||
|
||||
## 8. 领取前检查表
|
||||
|
||||
- [ ] 当前 task 与 parent manifest 的 `nextTask` 一致。
|
||||
- [ ] parent status 为 `done`,或明确写出允许并行的 `enablingTask`。
|
||||
- [ ] 任务卡只有一个主要行为。
|
||||
- [ ] focused command 已存在,或任务明确包含创建该命令。
|
||||
- [ ] 生产入口和测试入口分别列出,没有只写“相关代码”。
|
||||
- [ ] 至少一个负例、取消或重复事件已列出。
|
||||
- [ ] 任务状态不会误改 `parityStatus`/`releaseStatus` 另一条轴。
|
||||
- [ ] 完成后能生成 report、manifest、status 和可回滚路径。
|
||||
45
docs/TASK_CONTEXT_TEMPLATE.md
Normal file
45
docs/TASK_CONTEXT_TEMPLATE.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# 任务上下文模板
|
||||
|
||||
每张任务卡只允许一个主要行为变化或一个证据变化。保持短小;实现细节放在代码和测试中,运行结果
|
||||
放在 `docs/status/<task>.md`,不要在任务卡复制长日志。
|
||||
|
||||
## 任务
|
||||
|
||||
- `task`: `<ID>`
|
||||
- `parent`: `<parent ID>`
|
||||
- `status`: `pending | in_progress | done | blocked`
|
||||
|
||||
## 目标
|
||||
|
||||
一句话描述唯一可观察变化,以及明确不改变的状态轴。
|
||||
|
||||
## 输入
|
||||
|
||||
- 上一个 manifest:`tests/golden/<parent>/manifest.json`
|
||||
- 生产入口:`<protocol/worker/server path>`
|
||||
- 最小 fixture:`<fixture path or NOT_APPLICABLE>`
|
||||
|
||||
## 范围
|
||||
|
||||
- 做:
|
||||
- 不做:
|
||||
|
||||
## 验收
|
||||
|
||||
```text
|
||||
<focused command>
|
||||
```
|
||||
|
||||
适用时补充 Node、Chromium、typecheck、lint;每条命令必须真实运行并记录退出码。
|
||||
|
||||
## 产物和交接
|
||||
|
||||
- 报告:`tests/golden/<task>/...`
|
||||
- 状态页:`docs/status/<task>.md`
|
||||
- manifest:`tests/golden/<task>/manifest.json`
|
||||
- 下一任务:由 manifest 的 `nextTask` 决定
|
||||
|
||||
## 回滚
|
||||
|
||||
删除本任务新增的生产入口、测试、报告、manifest、package 命令和状态页,并将 parent manifest
|
||||
恢复为队列尾;不得删除或改写 parent 的成功证据。
|
||||
54
docs/status/M12-03E.md
Normal file
54
docs/status/M12-03E.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# M12-03E Status
|
||||
|
||||
status: done
|
||||
task: append undo/redo/save/reopen and desktop canonical comparison
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The M12-03D WASM Main append path is compared with the M12-03C Blender 5.2 desktop canonical
|
||||
report. One append transaction creates the Object/Mesh/Material/packed Image local closure and
|
||||
advances exactly one SceneIR revision. Undo removes all four IDs, redo restores the canonical
|
||||
graph, and a saved buffer reopens with the same graph and packed image pixels.
|
||||
|
||||
The image comparison normalizes Blender's bottom-up `Image.pixels` row order versus Canvas
|
||||
top-down `ImageData`. Current SceneIR omits `Image.colorSpace`, so a missing field uses the desktop
|
||||
canonical sRGB semantic default; an emitted colorspace must match it. All other graph, ID,
|
||||
ownership, geometry, UV, material-slot, image metadata, and pixel hash fields remain exact. This
|
||||
task does not claim Link, Library Override, or full N-023 IO parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node ../tools/web/check-library-main-append.mjs` passed the manifest, artifact hashes, canonical
|
||||
desktop report, and required test markers.
|
||||
- `WEB_TEST_PORT=5194 npm --prefix web run test:library-main-append` passed the checker and
|
||||
Chromium 1/1. The browser test verified one transaction, four writable `LOCAL_MAIN` mappings,
|
||||
one revision increment, complete Object -> Mesh -> Material -> Image closure, and exact
|
||||
canonical graphs after append, redo, and save/reopen.
|
||||
- A stale base revision returned `REVISION_CONFLICT`; a local ID collision returned
|
||||
`ASSET_MANIFEST_INVALID` without changing the appended revision. Undo reported no Object, Mesh,
|
||||
Material, or Image; redo restored the Object and canonical closure.
|
||||
- The canonical packed image remained a 2x2 sRGB RGBA PNG with Float32 pixel SHA-256
|
||||
`6f0f8c231d65149e69e6ed12d370bcfa095ef90adc202065492ea8c8ef17e45a`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `7fba72c5a38c0877f03682b51cbaaaf6d9a5f315f2beddfdef432bc54b2f1cd2`
|
||||
- test: `101f67d35c2320da57459f08a59687d769234b910dbd9aaec5a668cee7e0f9f0`
|
||||
- package commands: `36a29c5be9bd6163b06cf3511edf77d932388fa0b75c08bdcec397e19c0ef45f`
|
||||
- source `.blend`: `5b60d02926efd588a6ca300ba31414cdf37dbc48786c17b383a70319057c0606`
|
||||
- clean target `.blend`: `9b1ecbcc3d7f8079ee5469de64193ffcaa0a7b01e0f2ac340bbb18aa88734a63`
|
||||
- desktop report: `b1d7b8b9e832d18d69081f63981062800e0f00f0c9aec025b18274510ed76e2a`
|
||||
- manifest: `beaa88ea0385225e712f9816072420bd8744c15da3229ddc352462abec407739`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03F`: desktop link fixture preserving source library and read-only ownership.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M12-03E checker, manifest, extended Chromium test, package command, and this status
|
||||
entry. Restore M12-03D to pending and move the machine queue back to `M12-03D`. No parity ledger
|
||||
rollback is required.
|
||||
49
docs/status/M12-03F.md
Normal file
49
docs/status/M12-03F.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-03F Status
|
||||
|
||||
status: done
|
||||
task: create a desktop linked Object fixture preserving source-library ownership
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Blender 5.2 creates a source library containing one Object with a Mesh, Material, and packed Image
|
||||
dependency closure. A clean target links only the selected Object with `bpy.data.libraries.load(link=True)`.
|
||||
The Object, Mesh, Material, and Image retain the source library pointer, have no library override,
|
||||
and map to read-only `SOURCE_LIBRARY` ownership. The target is saved, reopened in a new Main load,
|
||||
and compared to the pre-save linked graph.
|
||||
|
||||
This task freezes the desktop LINK contract only. It does not implement a WASM link writer, linked
|
||||
mutation, reload/relocate, missing-library placeholders, or full N-023 parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-link-desktop` passed the manifest/artifact hash gate, Blender
|
||||
5.2 generator rerun, and canonical report comparison.
|
||||
- The fixture links one root and four dependency IDs. All three dependency edges, 4 vertices, 4
|
||||
edges, 1 polygon, 4 loops, `UVMap`, material slot, packed 2x2 sRGB RGBA image, and Float32 pixel
|
||||
SHA-256 `6f0f8c231d65149e69e6ed12d370bcfa095ef90adc202065492ea8c8ef17e45a` survive save/reopen.
|
||||
- Every linked ID reports `library=m12_link_source.blend` and `isLibraryOverride=false`; all four
|
||||
stable mappings are `SOURCE_LIBRARY/readOnly=true`. A temporary source/target regeneration matches
|
||||
the canonical report after normalizing only session-bound blend container hashes.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `15a2e34c1c5b2a8ee63b10084dbb894e0f9677b9e1cf4adb7e2ddce6b4c965b1`
|
||||
- checker: `6a4c024bea227d7bc14f793467b91766b006459fe4d7717cc75dfee12f49f894`
|
||||
- source `.blend`: `fae97569e9d2e2066fc92749672f86cc42717cd9b97b012faeb9eb92015d7fd1`
|
||||
- target `.blend`: `acdaf0f297deb08c84e1a8beba30972e3414ef62e60e3b103fe0661199c438a1`
|
||||
- desktop report: `b278d4c254eff63d41c8cb3ea1d5e0984192137d45b1695ba0672e16f95b58ea`
|
||||
- manifest: `8220a8f5d560d45a75a62cbed645b3febc1390fe37b07c3c48871fefc1a9b159`
|
||||
- package commands: `336d8df1914aaaafaeccc181d4e73ed7058165f10e167efe539939c3ac1e0536`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03G`: linked data writers must fail closed with `LINKED_DATA_MUTATION_BLOCKED`.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M12-03F link generator/checker, source and target fixtures, desktop report/manifest,
|
||||
package command, and this status entry. Restore M12-03E to pending and move the machine queue back
|
||||
to `M12-03E`. No parity ledger rollback is required.
|
||||
45
docs/status/M12-03G.md
Normal file
45
docs/status/M12-03G.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M12-03G Status
|
||||
|
||||
status: done
|
||||
task: block every linked data writer before Main mutation
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 linked mutation gate covers object transforms, mesh geometry, mesh material slots,
|
||||
material properties, material image nodes, and packed image data. Every request must identify a
|
||||
`SOURCE_LIBRARY` owner with `linkedLibrary=true` and `readOnly=true`. A current linked request is
|
||||
blocked with `LINKED_DATA_MUTATION_BLOCKED` before any Main writer can run; stale revisions remain
|
||||
`REVISION_CONFLICT`, and malformed or ownership-substituted requests fail closed.
|
||||
|
||||
This task does not claim a linked writer, reload, relocation, missing-library recovery, or full
|
||||
N-023 Link parity. The desktop linked ownership contract is the M12-03F input to this gate.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-linked-mutation` passed 3/3 unit tests.
|
||||
- All six linked writer operations return `BLOCKED` with exactly
|
||||
`LINKED_DATA_MUTATION_BLOCKED`, `recoverable=false`, and no Main mutation path. The test also
|
||||
verifies the schema round-trip for each operation.
|
||||
- A stale revision returns `REVISION_CONFLICT`; an unknown field, unsupported operation, or owner /
|
||||
read-only substitution returns `TASK_VALIDATION_FAILED` or `LINKED_DATA_MUTATION_BLOCKED` before
|
||||
any writer invocation.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `f629e0e7e04dc1f5437b6e2ca62fbe35484fc238830fa47e8358bcab46b7e104`
|
||||
- unit: `f19d47cefe89daf6123062e045ec717e6ffe60977e8a4b20c996dd62e49da211`
|
||||
- manifest: `890891fda5c91b08d157927170fb33190ae0d8a49f8962b88c8554307c0c06a8`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03H`: library reload replaces only the matching linked generation snapshot.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the linked mutation protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03F to pending and move the machine queue back to `M12-03F`. No parity ledger rollback
|
||||
is required.
|
||||
43
docs/status/M12-03H.md
Normal file
43
docs/status/M12-03H.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M12-03H Status
|
||||
|
||||
status: done
|
||||
task: library reload replaces only the matching linked generation snapshot
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 reload requests identify one `SOURCE_LIBRARY` and an expected generation/revision. The
|
||||
replacement must keep the same library identity, advance exactly one generation, advance the source
|
||||
revision, and retain a read-only source-library data-block closure. Only the unique matching snapshot
|
||||
is replaced; other libraries and other generations remain unchanged.
|
||||
|
||||
Malformed requests, duplicate state identities, owner substitution, skipped generations, and stale
|
||||
generation/revision requests fail closed before any Main mutation. A stale request returns
|
||||
`REVISION_CONFLICT` and an unchanged state.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-linked-reload` passed 4/4 unit tests.
|
||||
- The matching-generation case replaces one snapshot atomically while preserving a future generation
|
||||
and an unrelated library; the input state remains immutable.
|
||||
- Stale, malformed, duplicate, owner-substituted, and non-adjacent reload cases are rejected without
|
||||
publishing a partial state.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `8be6f0b2abe36cd566ea7447d1b7de44c0e6a9a7351b863dfdd1372c1761060e`
|
||||
- unit: `dff866291468cc01e775fe3b3b95c632f5c0742566f79b956a0193bfd8fd43d2`
|
||||
- manifest: `dd96702dcb064779de3fc33ce1200d75615e7b75a3418a45a309e0e612fdb7df`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03I`: missing library preserves a placeholder and the original source reference.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the linked reload protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03G to pending and move the machine queue back to `M12-03H`. No parity ledger rollback
|
||||
is required.
|
||||
42
docs/status/M12-03I.md
Normal file
42
docs/status/M12-03I.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-03I Status
|
||||
|
||||
status: done
|
||||
task: missing library preserves placeholder and original source reference
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 missing-library requests match a linked source library by source identity, generation, and
|
||||
revision. Marking a matching reference missing changes only its status and adds a
|
||||
`MISSING_LIBRARY` placeholder. The original locator, source SHA-256, generation, revision, and every
|
||||
data-block ID remain attached to the reference; unrelated libraries remain unchanged.
|
||||
|
||||
Stale generation/revision and source hash drift return a stable conflict without deleting or replacing
|
||||
the reference. Malformed fields, duplicate identities, and inconsistent placeholder data fail closed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-linked-missing` passed 4/4 unit tests.
|
||||
- The matching case preserves original source metadata and data-block IDs while publishing only the
|
||||
placeholder status transition.
|
||||
- Stale, source-drift, undeclared-field, duplicate-identity, and invalid-placeholder cases publish no
|
||||
partial state.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `5833e8c943ef6bd866a93a0e1666c9521fa6d3e8358861df57b628874b679ec2`
|
||||
- unit: `4ab6d6ff4845b4ca963399e7eea214ceb412871dc1fdef5bac1ed0333596da4f`
|
||||
- manifest: `f5fa606161b93e9ee42e7ca8144d2a83379acf601c5045eb8cc76732f8dba431`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03J`: desktop override fixture records reference, local owner, and property override path.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the missing-library protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03H to pending and move the machine queue back to `M12-03I`. No parity ledger rollback
|
||||
is required.
|
||||
45
docs/status/M12-03J.md
Normal file
45
docs/status/M12-03J.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M12-03J Status
|
||||
|
||||
status: done
|
||||
task: desktop override fixture records reference, local owner, and property override path
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Blender 5.2 creates a real linked Object and converts it through the library override API. The fixture
|
||||
records the linked reference as `SOURCE_LIBRARY/readOnly=true`, the local hierarchy root as
|
||||
`LOCAL_OVERRIDE/readOnly=false`, and one explicit custom-property override path. The source marker,
|
||||
reference ID, local owner, hierarchy root, property operation and value remain stable after save/reopen.
|
||||
|
||||
This fixture does not open a general override writer; it freezes the reference/owner/property contract
|
||||
needed by the next bounded writer task.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-override-desktop` passed.
|
||||
- Blender 5.2 source/target fixture regeneration matched the normalized desktop report.
|
||||
- The reference retains `m12_override_source.blend`; the local object is `LOCAL_OVERRIDE`; the only
|
||||
recorded property path is `["m12_override_value"]` with value `2.5` and one `REPLACE` operation.
|
||||
- Save/reopen preserves the reference, hierarchy root, owner semantics, and property metadata.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `2cdbac04cac7240360a9d70919380fd90f9479e2cb41d8032fb51626ed4b4dd6`
|
||||
- checker: `afebb3c9b8715b9d2e0c9b17f463f038bd23e8747074137bccbf1c09c4bfb5ba`
|
||||
- source blend: `d7f8d78e7e91481bf46ecc9a6bcb01e900a6a397839dd31ab80a53def7675601`
|
||||
- target blend: `b008a1608ff1e8f679e1e1281bf7be0360f1137e815dd890cbd93e1e98675495`
|
||||
- report: `19cb13a3417b4b65a8497b622337c42c4697b3f3d48de26a1f70f2d4527ddde0`
|
||||
- manifest: `01d0f66bb3819eea3e92727d1b5bffbec935d24eeecc28d874b999df78d73fbf`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03K`: expose exactly one verified override writer property.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the override generator/checker, fixture, report, manifest, package command, and this status
|
||||
entry. Restore M12-03I to pending and move the machine queue back to `M12-03J`. No parity ledger
|
||||
rollback is required.
|
||||
42
docs/status/M12-03K.md
Normal file
42
docs/status/M12-03K.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-03K Status
|
||||
|
||||
status: done
|
||||
task: expose exactly one verified override writer property
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 override writer accepts exactly `SET_M12_OVERRIDE_VALUE` for the property path
|
||||
`["m12_override_value"]`. It requires `LOCAL_OVERRIDE`, `readOnly=false`,
|
||||
`referenceReadOnly=true`, matching local/reference/hierarchy IDs, and the current revision. A valid
|
||||
write updates only the verified value and advances the local revision by one.
|
||||
|
||||
Linked ownership, a second property path, identity drift, stale revision, malformed fields, and values
|
||||
outside the bounded float range are blocked before any writer commit.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-override-writer` passed 4/4 unit tests.
|
||||
- The valid request applies one property and increments revision exactly once while preserving local
|
||||
override ownership and reference read-only semantics.
|
||||
- Stale, linked-owner, identity, alternate-operation, alternate-property, malformed, and out-of-range
|
||||
requests fail closed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `dd181c7e9946b98334a5d1c686887afecfe3fc11d732beec246e40bf11a155aa`
|
||||
- unit: `e41bd32eb4ce4d331a20ecb91f3325a27f461b9ae85e98940d5afd482ec21c4c`
|
||||
- manifest: `9eeee93e4a806aa59b5c53a6485fe3a1b5e3972c1d2585cdc71b7cfc293afb70`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03L`: block override stale source/revision before Main commit.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the override writer protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03J to pending and move the machine queue back to `M12-03K`. No parity ledger rollback
|
||||
is required.
|
||||
41
docs/status/M12-03L.md
Normal file
41
docs/status/M12-03L.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M12-03L Status
|
||||
|
||||
status: done
|
||||
task: block override stale source/revision before Main commit
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 override freshness binds the local override to its source library ID, source generation,
|
||||
source revision, dependency-closure SHA-256, invalidation token, and local/reference/hierarchy IDs.
|
||||
Only a fully matching `COMMIT_OVERRIDE` request reaches `READY`; no Main mutation is performed by
|
||||
this gate.
|
||||
|
||||
Stale generation/revision, dependency closure, invalidation token, linked ownership, identity drift,
|
||||
alternate operation, malformed token, and undeclared fields return stable blocking codes before Main.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-override-freshness` passed 4/4 unit tests.
|
||||
- The exact source generation/revision/closure/token binding returns `READY`.
|
||||
- Stale source fields return `REVISION_CONFLICT`; local identity drift returns
|
||||
`ASSET_SOURCE_HASH_MISMATCH`; linked ownership returns `LINKED_DATA_MUTATION_BLOCKED`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `2eff7ea7605b1579d7551336d87d4f30adb996b585596ff9eee67aea04ca7d22`
|
||||
- unit: `d48344f31e1ba12e557ca30ece56643583efa633da556f5de3896a8e9175ef8f`
|
||||
- manifest: `237f3f168e037b67b805ba8d9c9455250c889a5e90c45cbb17d2d20d9fbdcc50`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03M`: dependency cycle, ID collision, cross-library cycle, and duplicate reload negatives.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the override freshness protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03K to pending and move the machine queue back to `M12-03L`. No parity ledger rollback
|
||||
is required.
|
||||
38
docs/status/M12-03M.md
Normal file
38
docs/status/M12-03M.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M12-03M Status
|
||||
|
||||
status: done
|
||||
task: dependency cycle, ID collision, cross-library cycle, and duplicate reload negatives
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 negative-case validation checks library dependency graphs, cross-library references,
|
||||
data-block identity ownership, and reload generation identities. Acyclic graphs with unique IDs are
|
||||
accepted; dependency/cross-library cycles, missing source libraries, duplicate data-block IDs, and
|
||||
duplicate reload generations fail with stable codes before any writer or Main mutation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-negative-cases` passed 4/4 unit tests.
|
||||
- Direct dependency cycles and cross-library cycles return `LIBRARY_DEPENDENCY_CYCLE`.
|
||||
- Data-block collision returns `TASK_VALIDATION_FAILED`; duplicate reload returns `REVISION_CONFLICT`;
|
||||
a missing source library returns `ASSET_SOURCE_HASH_MISMATCH`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `efc7cc810089eab6178fc5c2f2a45d641625a032ecfa5b2b4ef37694d0decc97`
|
||||
- unit: `b7ae41b2c35b2fe1598bca4425dd434230bfe4bf342320c88214a060dcbb0a16`
|
||||
- manifest: `693cbedfe8e29167283a753d119de5a9cfe5e20bc96aff7ba84d720ffde9148a`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-03N`: append/link/override each receive independent desktop/WASM/Chromium commands.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the negative-case protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-03L to pending and move the machine queue back to `M12-03M`. No parity ledger rollback
|
||||
is required.
|
||||
42
docs/status/M12-03N.md
Normal file
42
docs/status/M12-03N.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-03N Status
|
||||
|
||||
status: done
|
||||
task: append/link/override each receive independent desktop/WASM/Chromium commands
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Append, LINK, and library override each have independent desktop, WASM, and Chromium commands. The
|
||||
commands are bound to distinct fixtures/protocol tests/browser specs and use separate Chromium ports.
|
||||
The command checker verifies all nine package entries and their lane-specific targets.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm run test:library-operation-commands` passed with 9 independent commands: 3 operations x 3 lanes.
|
||||
- Desktop: append fixture, LINK fixture, and Blender 5.2 override fixture all passed.
|
||||
- WASM: append receipt protocol passed 2/2; LINK aggregate passed 11/11; override aggregate passed 8/8.
|
||||
- Chromium: append passed 1/1; LINK gate passed 1/1 on port 5195; override writer passed 1/1 on port
|
||||
5196. Append Chromium passed 1/1 on port 5194.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- command checker: `3564347393134d835fdf279b8b8f58558ee24fe0165c3b4527195d094a451e98`
|
||||
- append WASM protocol: `bfd98561cbe797d7b8f07c92c53a25460c839a64ab7222b7795cf58d54dff8d7`
|
||||
- append WASM unit: `75fc2d626f7ca7e820e9cacf659a453886e15e790cde43348828c03bed752ec7`
|
||||
- append Chromium: `101f67d35c2320da57459f08a59687d769234b910dbd9aaec5a668cee7e0f9f0`
|
||||
- link Chromium: `814e3486522fb4f0ffdd59acd385a4fca9c5660cdb07e5a2acb1cadd70376bff`
|
||||
- override Chromium: `1c12982b4eb4fb4b9a3c88907a842a1fc413b3a3a760a9f57b350f57060d007f`
|
||||
- manifest: `e4cccc8edc277b5047c3f8006ea40b26b119d28589fe2f3bd9bfa4cc3575c85a`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04A`: library source schema accepts only declared HTTPS origins, project assets, or user-selected files.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the independent command checker, lane-specific tests/wrappers, manifest, package commands, and this
|
||||
status entry. Restore M12-03M to pending and move the machine queue back to `M12-03N`. No parity ledger
|
||||
rollback is required.
|
||||
40
docs/status/M12-04A.md
Normal file
40
docs/status/M12-04A.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# M12-04A Status
|
||||
|
||||
status: done
|
||||
task: library source schema accepts declared HTTPS origin, project asset, or user-selected file
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 source admission accepts exactly three declared kinds: HTTPS URLs whose credential-free origin
|
||||
is present in the policy, project-relative asset paths normalized by the existing project-path gate,
|
||||
and user-selected files carrying a stable selection ID, safe file name, bounded byte length, and
|
||||
source SHA-256. Accepted sources receive a canonical locator.
|
||||
|
||||
Undeclared origins, credentials, unsafe project paths, empty origin policy, malformed file identity,
|
||||
and undeclared fields fail closed before any library load.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-source-origin` passed 4/4 unit tests.
|
||||
- Declared HTTPS, project asset, and user-selected file cases return `READY` with canonical locators.
|
||||
- Undeclared HTTPS, credential-bearing URLs, traversal paths, empty policies, malformed selection IDs,
|
||||
and undeclared fields return stable blocking errors.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `67a1808f225194a09a72987c5340c7494c5fa8d99dffde40664a11a779caedeb`
|
||||
- unit: `89b207c9cb13b4fb055a2dfed0237c0f8a00b13a39cc4175a378f5ef2abdb7ae`
|
||||
- manifest: `af80827d925ddd96d8541e446e0f70c956fd4c56e64ac984d187f5449df4cb0d`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04B`: normalize POSIX/Windows separators, `.`, `..`, percent encoding, and Unicode names.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the source-origin protocol, unit suite, manifest, package command, and this status entry. Restore
|
||||
M12-03N to pending and move the machine queue back to `M12-04A`. No parity ledger rollback is required.
|
||||
42
docs/status/M12-04B.md
Normal file
42
docs/status/M12-04B.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M12-04B Status
|
||||
|
||||
status: done
|
||||
task: normalize POSIX/Windows separators, dot segments, percent encoding, and Unicode names
|
||||
updated: 2026-08-17 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The shared project-asset path normalizer now emits one canonical `/`-separated path. It accepts
|
||||
equivalent POSIX/Windows separators, removes `.` segments, resolves bounded `..` segments without
|
||||
allowing project-root escape, decodes percent-encoded UTF-8 once, and applies Unicode NFC normalization.
|
||||
Residual percent octets, malformed encoding, controls, absolute paths, URI schemes, and traversal beyond
|
||||
the project remain fail-closed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-path-normalization` passed 4/4 unit tests.
|
||||
- Separator and dot aliases converge to one idempotent canonical path.
|
||||
- Percent-encoded separators/dot segments and decomposed Unicode names match the canonical project asset
|
||||
locator used by the M12-04A source admission path.
|
||||
- Re-decoding, malformed percent encoding, and project-root escape return stable path errors.
|
||||
- `npm --prefix web run typecheck` passed after closing the prior library wrapper/parser type errors.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `af80827d925ddd96d8541e446e0f70c956fd4c56e64ac984d187f5449df4cb0d`
|
||||
- normalizer: `6109d05251fc7355ac32d4c0d8298f85ea8b731767c76c394577c4e44652a6bf`
|
||||
- source admission: `67a1808f225194a09a72987c5340c7494c5fa8d99dffde40664a11a779caedeb`
|
||||
- unit: `abde64c60397541e92a83dd9e4a24e65faf340a8d046650604c101a21037c777`
|
||||
- manifest: `8cd29c3f5281082584fc6aefe2ec385a2eedf8116e837a4db54c391391ff8f98`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04C`: reject absolute paths, UNC, drive paths, NUL, control characters, and origin escape.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the path normalizer changes, unit suite, manifest, package command, and this status entry. Restore
|
||||
M12-04A to pending and move the machine queue back to `M12-04B`. No parity ledger rollback is required.
|
||||
45
docs/status/M12-04C.md
Normal file
45
docs/status/M12-04C.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M12-04C Status
|
||||
|
||||
status: done
|
||||
task: reject absolute paths, UNC/drive paths, controls, and origin escape
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The project-asset path gate rejects absolute POSIX paths, UNC and drive-shaped paths, NUL/control
|
||||
characters, malformed or residual percent encoding, and URI/origin-shaped escapes before a locator is
|
||||
accepted. HTTPS source policy entries are now strict credential-free origins: path, query, fragment,
|
||||
encoded controls, and backslash smuggling are rejected instead of being silently reduced to
|
||||
`URL.origin`. HTTPS resource paths retain the declared-origin check and reject unsafe decoded bytes.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-path-security` passed 4/4 unit tests.
|
||||
- Absolute, UNC, drive, raw/encoded NUL and control characters, and origin-style project paths return
|
||||
stable `ASSET_PATH_OUTSIDE_PROJECT`/`ASSET_PATH_INVALID` errors.
|
||||
- Raw and encoded backslashes, controls, malformed percent sequences, credentials, undeclared origins,
|
||||
and policy origin smuggling return `IO_EXTERNAL_URI_BLOCKED`.
|
||||
- Declared `https://assets.example.test/library/main.blend` remains accepted; policy declarations with
|
||||
a path, query, fragment, encoded control, or duplicate canonical origin fail closed.
|
||||
- `WEB_TEST_PORT=5323 npm --prefix web run test:asset-library` passed the N-023 Chromium asset/IO gate 1/1.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `8cd29c3f5281082584fc6aefe2ec385a2eedf8116e837a4db54c391391ff8f98`
|
||||
- path normalizer: `6109d05251fc7355ac32d4c0d8298f85ea8b731767c76c394577c4e44652a6bf`
|
||||
- source-origin protocol: `67a1808f225194a09a72987c5340c7494c5fa8d99dffde40664a11a779caedeb`
|
||||
- unit: `ab302cacb24634a3225dda5cb8f5282cb80b3bd81ed5c8900ddf4ff18267b7e2`
|
||||
- manifest: `a7f3a45eb7f68d022f38185a1c1409e1db1b27647fef587d66d2ffa52d78f98e`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04D`: resolve symlink/hardlink entries before writing and constrain them to the temporary root.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the C path-security assertions, manifest, status entry, and strict origin validation. Restore
|
||||
M12-04B to pending and move the machine queue back to `M12-04C`. No parity ledger rollback is required.
|
||||
44
docs/status/M12-04D.md
Normal file
44
docs/status/M12-04D.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M12-04D Status
|
||||
|
||||
status: done
|
||||
task: resolve symlink/hardlink entries before writing and constrain them to the temporary root
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Archive entries are parsed before any write. Every member is canonicalized as a relative path under
|
||||
the declared temporary-root identity. Symlink targets resolve relative to the link's parent; hardlink
|
||||
targets resolve from the archive root and must end at a regular file. Absolute, drive-shaped, URI,
|
||||
backslash-smuggled, traversal, missing-target, cyclic, duplicate, and hardlink-to-directory inputs
|
||||
fail closed with `IO_ARCHIVE_UNSAFE`.
|
||||
|
||||
The resolver returns a write plan with the final in-root target and an explicit
|
||||
`withinTemporaryRoot: true` proof for every member. It does not follow or write any link before the
|
||||
entire manifest has passed validation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-link-safety` passed 5/5 unit tests.
|
||||
- Parent-directory symlinks, archive-root hardlinks, and chained links resolve to canonical in-root
|
||||
members.
|
||||
- Absolute/UNC/drive/URI/traversal targets, missing members, cycles, duplicate paths, undeclared
|
||||
fields, and hardlinks to directories are rejected before a write plan is returned.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `a7f3a45eb7f68d022f38185a1c1409e1db1b27647fef587d66d2ffa52d78f98e`
|
||||
- protocol: `d55a4ba762898aed22bdcc7aa6493c713ee94f6bb1bf58754fdc459d0ddf70d1`
|
||||
- unit: `7739275be91222d7bfb61d2f5a1daf812c6860fe34d0aea27df8380a77322120`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04E`: archive first reads the central directory/manifest and does not extract payload first.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the archive link-safety protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-04C to pending and move the machine queue back to `M12-04D`. No parity ledger rollback is
|
||||
required.
|
||||
38
docs/status/M12-04E.md
Normal file
38
docs/status/M12-04E.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M12-04E Status
|
||||
|
||||
status: done
|
||||
task: archive first reads the central directory or manifest before payload extraction
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
ZIP requests produce a bounded `CENTRAL_DIRECTORY` first-read plan; TAR requests produce a bounded
|
||||
`MANIFEST` first-read plan. The plan contains no payload ranges. A read trace is accepted only when
|
||||
the first exact range is the declared metadata range and every later range is payload; payload-first,
|
||||
wrong-range, duplicate-metadata, out-of-order, oversized, and out-of-archive reads fail closed with
|
||||
`IO_ARCHIVE_UNSAFE`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-metadata-first` passed 4/4 unit tests.
|
||||
- ZIP and TAR plans expose metadata-only first reads with an empty payload plan.
|
||||
- Payload-first, wrong-range, duplicate metadata, out-of-archive, and metadata-budget cases are
|
||||
rejected before extraction can be scheduled.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `1c09abd1f4bd5908d22ab3b22e3e71d050f694af0b82a7f78a351d7a1bf1e664`
|
||||
- protocol: `869586b041e134c7d1cb2ebd7e13b35218b337223d401697a179f71cd1420f5b`
|
||||
- unit: `2da649722acee9cace8db6f337b4a93500a9c775a0b0f086bf38dd2b3e7f9e91`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04F`: enforce per-entry bytes, total bytes, entry count, directory depth, and filename length budgets.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the metadata-first protocol, unit suite, manifest, package command, and this status entry. Restore
|
||||
M12-04D to pending and move the machine queue back to `M12-04E`. No parity ledger rollback is required.
|
||||
37
docs/status/M12-04F.md
Normal file
37
docs/status/M12-04F.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M12-04F Status
|
||||
|
||||
status: done
|
||||
task: enforce archive entry, total, count, directory-depth, and filename-length budgets
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production `asset-library-io` parser now enforces the existing compressed/uncompressed per-entry
|
||||
and total-byte budgets together with a 100,000-entry limit, 64 directory levels, and a 255-byte UTF-8
|
||||
filename limit. Compression-ratio and declared source-byte checks remain fail-closed in the same path.
|
||||
Budget checks happen while parsing metadata, before any payload allocation or extraction.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-archive-budget` passed 4/4 unit tests.
|
||||
- Exact boundary cases for entry bytes, total bytes, entry count, directory depth, and Unicode filename
|
||||
bytes are accepted; one-byte overflows return stable budget errors.
|
||||
- Existing compression-ratio, duplicate/prefix, and declared source-byte checks remain covered.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `d935392fb23c2e6ad651fb6ad6cb67f8ead3d562e626bb230d2febd9d7f03b1c`
|
||||
- protocol: `e02efa79668f4ee10b1c28786709eba2c93691b28ccf1155c6213dda12f59a8f`
|
||||
- unit: `b0d8356c6fb348d98e28ce220052845a29439b34b3c976b21a4dbf370ea19593`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04G`: reject compression-ratio, overlapping range, duplicate path, and file/directory prefix conflicts.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the budget checks, unit suite, manifest, package command, and this status entry. Restore M12-04E
|
||||
to pending and move the machine queue back to `M12-04F`. No parity ledger rollback is required.
|
||||
39
docs/status/M12-04G.md
Normal file
39
docs/status/M12-04G.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# M12-04G Status
|
||||
|
||||
status: done
|
||||
task: reject archive compression bombs, overlapping ranges, duplicate paths, and prefix conflicts
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Archive range validation now checks each compressed range against the declared source length and the
|
||||
global archive bound, sorts ranges by offset, and rejects overlap before any payload read. It also
|
||||
rejects duplicate canonical paths, file/directory prefix conflicts, zero-byte compression bombs, and
|
||||
expansion ratios above 100:1. Valid ranges return deterministic totals and explicit non-overlap/path
|
||||
invariants.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-archive-conflicts` passed 4/4 unit tests.
|
||||
- Non-overlapping ranges produce stable compressed/uncompressed totals.
|
||||
- Compression-ratio, overlap, duplicate, prefix, source-bound, and undeclared-field negatives all
|
||||
return `IO_ARCHIVE_UNSAFE` before payload scheduling.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `cda905b1e27b62d9ea3a05170f975015480ce6739c15bdf1f5a1f0b79f93ce06`
|
||||
- protocol: `3bec372e4f67ec309f28534cebcbaf8b492144adfa82ff6c8603f88c3ba16254`
|
||||
- unit: `3f2d44dce33b1c17b3a48f58b04fdd821abc88d98ce3d3b5bb724859e0f0ab3c`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04H`: cancellation removes staging and never modifies the committed project.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the archive conflict protocol, unit suite, manifest, package command, and this status entry.
|
||||
Restore M12-04F to pending and move the machine queue back to `M12-04G`. No parity ledger rollback is
|
||||
required.
|
||||
48
docs/status/M12-04H.md
Normal file
48
docs/status/M12-04H.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# M12-04H Status
|
||||
|
||||
status: done
|
||||
task: remove extraction staging on cancellation without modifying the committed project
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production archive extraction transaction checks cancellation before staging, around every
|
||||
payload read and write, and immediately before atomic commit. A pre-commit cancellation returns
|
||||
`IO_ARCHIVE_CANCELLED`, removes every staged file, publishes no project, and re-reads the committed
|
||||
project identity to prove that revision and SHA-256 did not change. Once atomic commit starts,
|
||||
cancellation no longer converts the completed commit into a cancelled result.
|
||||
|
||||
Payload identity failure and staging creation/write failure use the same cleanup path. If cleanup
|
||||
leaves a staged entry or the committed identity drifts, the transaction fails with
|
||||
`STORAGE_TRANSACTION` instead of claiming successful cancellation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:library-archive-cancellation` passed 6/6 unit tests against real
|
||||
temporary directories.
|
||||
- Cancellation before staging, after one staged file, and after the final staged write all leave
|
||||
zero staging files, zero published projects, and the original committed project bytes.
|
||||
- The success path publishes revision 9 only after both staged payload hashes pass.
|
||||
- Payload mismatch, rollback identity drift, stale revision, unsafe path, prefix conflict, and
|
||||
undeclared-field negatives fail closed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `c35e675e8f512e85b748f0b5578874fed8c99df7674a152e698236a67c9f4fa4`
|
||||
- protocol: `c40adc1449172014cc1820db567e155828314abb404b66e4de13c26ddee06e4b`
|
||||
- error codes: `751c70c898540fa7e82fb1b1a79254756ec8db8e4201a88b6d817d7c3d92103f`
|
||||
- unit: `77e7d5bc64dd6b313006ebf523602601acdaf7949a1484da872ddcd046983786`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `7fce600a416aec5ade1a91a13d86caf4cb1f65b710054b59d525ff8b1d3c7409`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04I`: release temporary files after quota/OOM and allow a small archive to recover.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the extraction transaction protocol, cancellation code, real-filesystem unit suite, manifest,
|
||||
package command, and this status entry. Restore M12-04G as the queue tail and move the machine queue
|
||||
back to `M12-04H`. No parity ledger rollback is required.
|
||||
47
docs/status/M12-04I.md
Normal file
47
docs/status/M12-04I.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# M12-04I Status
|
||||
|
||||
status: done
|
||||
task: release archive staging after quota/OOM and recover with a small archive
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The archive recovery wrapper maps browser/OPFS quota failures to `STORAGE_QUOTA` and declared
|
||||
allocation failures to `WASM_OUT_OF_MEMORY` only after the M12-04H base transaction has removed
|
||||
staging and re-read the committed project identity. Cleanup or identity drift remains
|
||||
`STORAGE_TRANSACTION`; unrelated range and IO failures are not misclassified as OOM.
|
||||
|
||||
Real temporary-directory tests partially write the failing payload before injecting each fault.
|
||||
Both paths leave zero staging entries and preserve the previous revision, SHA-256, and committed
|
||||
bytes. The same storage instance then accepts and atomically commits a smaller archive without a
|
||||
Worker or process restart.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/library-archive-recovery.test.mjs` passed 4/4.
|
||||
- Quota and OOM each remove a partially written 4 KiB staging payload and preserve revision 9.
|
||||
- Each failed storage instance immediately commits `small-project` at revision 10 with zero
|
||||
staging entries.
|
||||
- `npm --prefix web run test:library-archive-cancellation` passed 6/6 and
|
||||
`npm --prefix web run typecheck` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `7fce600a416aec5ade1a91a13d86caf4cb1f65b710054b59d525ff8b1d3c7409`
|
||||
- base transaction: `c40adc1449172014cc1820db567e155828314abb404b66e4de13c26ddee06e4b`
|
||||
- recovery protocol: `0ae9801ea151403b244c5f58f7f99231bba7a25abb1f61e3669879510b92dccf`
|
||||
- unit: `a931edef8f3ca1243a80ec2b8e9ff5b8da1dfd339f3d8c162ad2ebd08d3db6a1`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `574afa68a787b9481d0e098d38b94cb810a9827fe185b0df796d62cc160ba7c5`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-04J`: add malicious ZIP/TAR fixtures to the long-term security regression.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the recovery wrapper, real-filesystem unit suite, manifest, and this status entry. Restore
|
||||
M12-04H as the queue tail and move the machine queue back to `M12-04I`. No parity ledger rollback is
|
||||
required.
|
||||
49
docs/status/M12-04J.md
Normal file
49
docs/status/M12-04J.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-04J Status
|
||||
|
||||
status: done
|
||||
task: keep malicious ZIP/TAR fixtures in the long-term archive security regression
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Six deterministic binary fixtures cover ZIP path traversal, compression-ratio abuse, duplicate
|
||||
paths, TAR path traversal, symlink escape, and file/directory prefix conflict. The generator fixes
|
||||
container fields and timestamps; the checker regenerates every file in a temporary directory and
|
||||
requires byte-for-byte equality with the committed fixtures and catalog SHA-256 values.
|
||||
|
||||
The checker reads ZIP EOCD/central-directory and USTAR header metadata, verifies local-header
|
||||
bindings, TAR checksums, alignment, and end markers, then feeds the actual entry metadata into the
|
||||
M12-04D/G link and conflict gates. It never invokes `tar`, `unzip`, or an extraction API. All six
|
||||
fixtures fail closed with `IO_ARCHIVE_UNSAFE` and are included in the existing N-023 Chromium grep.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-malicious-archive-fixtures.mjs` passed 6/6 with three ZIP and three TAR
|
||||
fixtures and extraction disabled.
|
||||
- `WEB_TEST_PORT=5408 npm --prefix web run test:asset-library` passed 2/2, including the persistent
|
||||
binary-fixture security test and the existing N-023 asset/IO gate.
|
||||
- Fixture byte lengths range from 115 to 3,072 bytes and every committed SHA-256 matches the
|
||||
generated catalog.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `574afa68a787b9481d0e098d38b94cb810a9827fe185b0df796d62cc160ba7c5`
|
||||
- generator: `b372ea8cb2f97b035ffb2cc18666dae9167dcfb349131851ad9f1ff0fc40ba16`
|
||||
- checker: `edda2f420f26e55f9990d24b755bb9b4f732ec32c2e072210144b3d0b6634d9b`
|
||||
- fixture manifest: `a93834316f6a23b8a0e6c1f1f806ec584d6f03aa339c2680cae2ce8133a40e58`
|
||||
- Chromium spec: `f327500808dd67359a152ce28134b58d027aebd6758416b5535b659b9900bbfe`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `989d417ab44e165849c7054f331f7038ec1d779349c39dd4f5b30050bbaecf56`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05A`: generate the glTF/GLB, OBJ, STL, PLY, USD, and Alembic format inventory from the pinned
|
||||
Blender 5.2 build/runtime.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the fixture generator/checker, six binary fixtures and catalog, Chromium spec, golden
|
||||
manifest, and this status entry. Restore M12-04I as the queue tail and move the machine queue back to
|
||||
`M12-04J`. No parity ledger rollback is required.
|
||||
49
docs/status/M12-05A.md
Normal file
49
docs/status/M12-05A.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-05A Status
|
||||
|
||||
status: done
|
||||
task: generate the Blender 5.2 runtime format inventory
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The pinned `build_blender_5.2.0/bin/blender` runtime generated seven separate format records:
|
||||
GLTF, GLB, OBJ, STL, PLY, USD, and ALEMBIC. Each record binds import/export operator paths,
|
||||
registered state, RNA identifier, canonical property identifiers and enum items, file extensions,
|
||||
format variants, and the build option that gates the operator.
|
||||
|
||||
The runtime receipt also binds Blender 5.2.0 LTS version tuple, build hash/branch/platform/type/date,
|
||||
commit timestamp, selected build options, and the Blender binary SHA-256. On this pinned build,
|
||||
GLTF/GLB/OBJ/STL/PLY are `AVAILABLE`; USD and Alembic are explicitly `OPERATOR_UNREGISTERED` because
|
||||
`bpy.app.build_options.usd` and `alembic` are false. This is inventory evidence only and does not
|
||||
claim import/export round-trip parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-io-format-runtime-inventory.mjs` passed; the generator was rerun in a fresh
|
||||
process and matched the committed JSON byte-for-byte.
|
||||
- Inventory has 7 formats, 5 available format families and 2 build-disabled families. All available
|
||||
operators have canonical non-empty RNA property lists; disabled operators fail closed.
|
||||
- Runtime receipt records binary SHA-256
|
||||
`d4483926610484ef9c2ad9241aae1469f934d955ebe791f1920e263e0ba85b82`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `989d417ab44e165849c7054f331f7038ec1d779349c39dd4f5b30050bbaecf56`
|
||||
- generator: `aa926397664240a5195f8864fc3ed5549bafcc963a03c513c7e37926b0559d7d`
|
||||
- checker: `12853306ea5eb2698ab636c7dfc2f27ae140295641473c57b84f93fa13d4864e`
|
||||
- inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `202b144c91f8e2c39477e257aeb26f9bd0b1b05b459ff8a246668024e94deec7`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05B`: declare import/export, local/server, geometry/material/animation support separately for
|
||||
each inventoried format.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the runtime inventory generator/checker, format inventory, golden manifest, and this status
|
||||
entry. Restore M12-04J as the queue tail and move the machine queue back to `M12-05A`. No parity
|
||||
ledger rollback is required.
|
||||
48
docs/status/M12-05B.md
Normal file
48
docs/status/M12-05B.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# M12-05B Status
|
||||
|
||||
status: done
|
||||
task: declare per-format import/export local/server and feature support
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 capability matrix binds all seven M12-05A runtime formats and the inventory SHA-256.
|
||||
Each format has separate IMPORT and EXPORT entries with local and server routes plus explicit
|
||||
geometry, material, and animation feature status. A runtime operator being registered does not
|
||||
make a Web route executable.
|
||||
|
||||
The only `READY` route is the existing bounded GLB EXPORT local path. All seven IMPORT routes and
|
||||
all server routes are explicit `BLOCKED/IO_FORMAT_UNSUPPORTED`; other local exports are also blocked.
|
||||
GLB export features are marked `PARTIAL` with the M12-06 round-trip dependency. Unimplemented
|
||||
operations stay `UNVERIFIED` rather than claiming geometry/material/animation support.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-capability-matrix.test.mjs` passed 3/3, including duplicate
|
||||
format, ready-without-executor, unverified-ready-feature, and missing blocked-code negatives.
|
||||
- `node tools/web/check-io-format-capability-matrix.mjs` passed; the matrix generator reproduced the
|
||||
committed JSON byte-for-byte and runtime statuses matched the M12-05A inventory.
|
||||
- The checker reports 7 formats, 1 local bounded GLB export route, and 27 blocked routes.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `202b144c91f8e2c39477e257aeb26f9bd0b1b05b459ff8a246668024e94deec7`
|
||||
- protocol: `3063ae5e45f5b1642d329aa554187d121998d816a5a6740a2b9662f00c3c5738`
|
||||
- generator: `746078caaf29fa5aa2281b901b9ea5fc66f9a935eb3f6e282d4fbfb018d4c390`
|
||||
- checker: `4a8b35cd7f87238c13627a00c3bb0b34c130fc34d597773574efac7d8909b804`
|
||||
- unit: `0cc4d8f1df1ecdab20d8100cf5f12b44cb2a68bca4384ef7964a032b2f74b36e`
|
||||
- matrix: `139c9d764736da176b32414ecda840c07eb0ba5f3864da2dc08ce04bae161366`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `8cc9517c9f25138c351bc5a79efe3b1ce6d9f6663d3b7c14397c5e4e8f11181a`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05C`: prevent matrix-undecared combinations from appearing in file selection and operator search.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the capability matrix protocol/generator/checker, unit test, matrix, golden manifest, and this
|
||||
status entry. Restore M12-05A as the queue tail and move the machine queue back to `M12-05B`. No
|
||||
parity ledger rollback is required.
|
||||
52
docs/status/M12-05C.md
Normal file
52
docs/status/M12-05C.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# M12-05C Status
|
||||
|
||||
status: done
|
||||
task: prevent matrix-undeclared combinations from appearing in file selection and operator search
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 UI registry is generated from the M12-05B capability matrix and is bound to its exact
|
||||
SHA-256. Only routes whose runtime operator is `AVAILABLE` and whose local matrix route is `READY`
|
||||
are exposed to the UI. The current registry therefore accepts `.blend` projects, exposes the existing
|
||||
bounded local GLB export command, and exposes no blocked import or export route.
|
||||
|
||||
The file input uses the registry-derived accept string and performs a second filename gate before
|
||||
opening. A matrix-blocked or unknown extension returns `IO_FORMAT_UNSUPPORTED` without invoking the
|
||||
engine or replacing the current scene. Operator search filters every format-tagged command through the
|
||||
same registry, so blocked server routes and undeclared formats cannot appear as executable results.
|
||||
|
||||
## Evidence
|
||||
|
||||
- Direct M12-05C lane passed: `node --test web/tests/unit/io-format-ui-gate.test.mjs`,
|
||||
`node tools/web/check-io-format-ui-gate.mjs`, and Chromium 1/1 on dynamic ports 5413/5417.
|
||||
- `node tools/web/check-io-format-ui-gate.mjs` reproduced the committed registry byte-for-byte;
|
||||
import routes=0, local export routes=1, project accept=`.blend,application/octet-stream`.
|
||||
- `npm --prefix web run typecheck` and `npm --prefix web run build` passed.
|
||||
- `WEB_TEST_PORT=5412 npm --prefix web run test:asset-library` passed 2/2 N-023 Chromium regressions.
|
||||
- An initial command without `WEB_TEST_PORT` was blocked by an already occupied 5173; rerunning on the
|
||||
isolated dynamic port passed and left no server/profile process in the test lane.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `8cc9517c9f25138c351bc5a79efe3b1ce6d9f6663d3b7c14397c5e4e8f11181a`
|
||||
- protocol: `fc397ceb947d4ede6c34c1d51438253a6b59244fc40f5eb77ce155bf1c477476`
|
||||
- generator: `1ef4ae8a3e8d2f73101a87cba1c42ea99a065e1f6846f6a591841b97c0c39e6f`
|
||||
- checker: `81d6f27df26aab7b633fbe61c6d7b37519668aff41e43314924dceaacb3affde`
|
||||
- unit: `84ca8fb6022da9f167daa104c44489a6c7d9f059699e57ce621b8d7f64f19082`
|
||||
- Chromium: `eda2cdb9ede3bcbd717800c9c6fdb28d8cebef96f0296a2ee847a05e60cd0eed`
|
||||
- registry: `6b410bc6f2cad032af55bf13e1c8ddd841b01e9913ffc0ba381da8b7204285fd`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `f46fd394e2144255d8b4304e8ce4fe60aad4302a80e991fd83d50cd915235ee3`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05D`: determine capability from runtime receipts and never infer it from filename extensions.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the UI registry protocol, generator/checker, registry, unit/Chromium tests, package command,
|
||||
golden manifest, and this status entry. Restore M12-05B as the queue tail and move the machine queue
|
||||
back to `M12-05C`. No parity ledger rollback is required.
|
||||
54
docs/status/M12-05D.md
Normal file
54
docs/status/M12-05D.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# M12-05D Status
|
||||
|
||||
status: done
|
||||
task: determine format capability from pinned Blender runtime receipts, never filename extensions
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 runtime receipt set is generated from the pinned Blender 5.2 M12-05A inventory and
|
||||
bound to that inventory's SHA-256. Each format/operation receipt preserves the operator path, RNA
|
||||
identifier, registered state, build option state, variants, and descriptive extensions. A route is
|
||||
`READY` only when the receipt says `AVAILABLE`, the operator is registered, an RNA identifier exists,
|
||||
and the build option is not disabled.
|
||||
|
||||
The route resolver takes an explicit format and operation from the receipt and never parses a file
|
||||
name or extension to grant capability. App filters format-tagged operator search entries and checks
|
||||
the GLB export route against this receipt set immediately before execution. The pinned runtime marks
|
||||
GLB export `READY`; USD/Alembic receipts are `OPERATOR_UNREGISTERED` and remain blocked.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-runtime-receipt.test.mjs` passed 3/3, covering receipt-bound
|
||||
GLB/USD routes, extension mutation without capability change, identity drift, and explicit status.
|
||||
- `node tools/web/check-io-format-runtime-receipts.mjs` passed; a fresh generator process reproduced
|
||||
14 receipts byte-for-byte from M12-05A inventory and verified operator/runtime identity fields.
|
||||
- `npm --prefix web run typecheck` and `npm --prefix web run build` passed; M12-05C Chromium UI
|
||||
regression passed 1/1 on port 5417 and N-023 asset/security regression passed 2/2 on port 5418.
|
||||
- The existing frozen package hash `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
is preserved; dedicated commands remain direct to avoid invalidating prior release evidence.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `f46fd394e2144255d8b4304e8ce4fe60aad4302a80e991fd83d50cd915235ee3`
|
||||
- protocol: `461a84557fa368c29dbc6707959b689faae7c8f7050dccc4d3f12e358b61bb22`
|
||||
- generator: `796cd641e86d8242c13317f771ae237cbf1692ff675a53bbdb689615edb5f372`
|
||||
- checker: `aaf9862041f155f96f50ea8481ff765089255bc59ecd8944f12362b81b8c1f1a`
|
||||
- unit: `a5f09277f5dcdacd25c44191f7407d6cee944f8022b1c467c2a69e172fc2ac6b`
|
||||
- runtime receipts: `f2c9a77e2cfad0ef3574b804fc06fb22972c07f55c72b0e6db2e359c4d95f57b`
|
||||
- App receipts: `f2c9a77e2cfad0ef3574b804fc06fb22972c07f55c72b0e6db2e359c4d95f57b`
|
||||
- App: `74216aac70992f8d879e983237ca324b998008582f0cd4658e90994cf9fae0a8`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `3d0049a7b0331f01bb71df043270c18d1a5c9ce6dc74353c49c8ce591761df1b`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05E`: bind each runtime receipt to source, settings, and runtime hashes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the runtime receipt protocol, generator/checker, receipt set, App gate, unit test, golden
|
||||
manifest, and this status entry. Restore M12-05C as the queue tail and move the machine queue back to
|
||||
`M12-05D`. No parity ledger rollback is required.
|
||||
49
docs/status/M12-05E.md
Normal file
49
docs/status/M12-05E.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-05E Status
|
||||
|
||||
status: done
|
||||
task: bind every runtime receipt to source, settings, and runtime hashes
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 bound receipt set derives from M12-05A inventory and M12-05D runtime receipts. Every
|
||||
one of the 14 format/operation records carries three independent SHA-256 values: a source/operator
|
||||
identity hash, a settings/schema hash (including canonical variants/extensions and Blender RNA
|
||||
properties), and a runtime identity hash. The set also binds the parent M12-05D receipt-set hash and
|
||||
the M12-05A inventory hash.
|
||||
|
||||
The validator requires all three hashes and parent identities before a bound receipt can be resolved.
|
||||
The generator uses sorted-key canonical JSON and the checker independently recomputes every hash,
|
||||
then rebuilds the artifact in a fresh process for byte-for-byte determinism. No package metadata was
|
||||
changed, preserving the existing release evidence hash.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-receipt-binding.test.mjs` passed 2/2: valid three-hash
|
||||
resolution plus malformed source/settings/runtime and parent identity rejection.
|
||||
- `node tools/web/check-io-format-receipt-bindings.mjs` passed; all 14 source/settings/runtime hashes
|
||||
and parent/inventory identities matched a fresh deterministic regeneration.
|
||||
- `npm --prefix web run typecheck` passed; `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `3d0049a7b0331f01bb71df043270c18d1a5c9ce6dc74353c49c8ce591761df1b`
|
||||
- protocol: `681e719ab2b18eb85d056547fb70b461dd73b3a7fb4fdbe6295b8e49d5649e49`
|
||||
- generator: `eb7b5c499f141c1788bc37e53585662eedff3f2dabff870f4ad166f4a619796f`
|
||||
- checker: `ec2b22b468809ecc25ab2d4983065680a66ad3be6705d1827b44bf45ac622e26`
|
||||
- unit: `e9ae3e360ad41c32da3634a4efa915654853e79a35df36728c1ddf586a0bf7b5`
|
||||
- bound receipts: `7f765bf16b62466f579b3de00751a0e012fef1c788f229c8e9675a57caa18aad`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `PENDING`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-05F`: reject forged, stale, or cross-version runtime receipts before use.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the binding protocol, generator/checker, bound receipt golden, unit test, manifest, and this
|
||||
status entry. Restore M12-05D as the queue tail and move the machine queue back to `M12-05E`. No
|
||||
parity ledger rollback is required.
|
||||
54
docs/status/M12-05F.md
Normal file
54
docs/status/M12-05F.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# M12-05F Status
|
||||
|
||||
status: done
|
||||
task: reject forged, stale, or cross-version runtime receipts before use
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The schema-1 freshness envelope is derived from the M12-05E bound receipt set. It carries the
|
||||
M12-05E byte identity, a canonical digest of the complete bound receipt set, and a canonical digest
|
||||
of the pinned Blender runtime identity. Before a route can be used, the parent binding hash,
|
||||
inventory hash, runtime identity, runtime hash, and receipt-set hash must all match the trusted
|
||||
expectation. The route resolver re-validates this gate on every use and only then returns `READY`.
|
||||
|
||||
Forged receipt content returns `RECEIPT_FORGED`; an older parent or inventory returns
|
||||
`RECEIPT_STALE`; a different Blender version/build identity returns `RECEIPT_CROSS_VERSION`.
|
||||
Malformed or unavailable routes remain fail-closed as `IO_FORMAT_UNSUPPORTED`. The App GLB export and
|
||||
format-tagged operator search now consume the freshness envelope rather than the unbound M12-05D set.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-receipt-freshness.test.mjs` passed 4/4: exact trusted route,
|
||||
canonical digest verification, forged content, stale parent, and cross-version negatives.
|
||||
- `node tools/web/check-io-format-receipt-freshness.mjs` passed; 14 receipts, App artifact parity,
|
||||
independent canonical digest verification, deterministic regeneration, and all three negative
|
||||
classes passed.
|
||||
- Existing M12-05D/M12-05E unit and checker commands passed unchanged.
|
||||
- `npm --prefix web run typecheck` and `npm --prefix web run build` passed; `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `2fbaaf39c6acd9f55fbdbadccc0b027e9e7763bf069c954a96ca49b193648990`
|
||||
- protocol: `111a630c7beccd31989dc4f78932b7d7b741fb6bef03e45cb39a8139f774d235`
|
||||
- generator: `6a1e798ce46e1d14d833091d4d7ae452dccb13efe583594277785465eb725bbf`
|
||||
- checker: `7a8fe69ea1aa2c1e121be008a9fb60fc236f7ef776d2088a7b00b14f46fe3fba`
|
||||
- unit: `cd1c2adca81653f98f9a1c6c7d104ad0e3052283213fb7166dac827c956928fe`
|
||||
- freshness receipts: `0187ad0d9ea05fc4b152b7abd4945191dbe9ec24dfde4ca7dbe4aadfd1230efe`
|
||||
- App freshness receipts: `0187ad0d9ea05fc4b152b7abd4945191dbe9ec24dfde4ca7dbe4aadfd1230efe`
|
||||
- App expected identity: `8d65f78aa774ff252871cb1cc09e69b4ff04fbb45e61200eaf67534c9d2651b2`
|
||||
- App: `043ff3a2f39ef3a1303791081b80851b427e7db5dfd9af2161926dd6f1ea9ca4`
|
||||
- package commands: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `63e1506801ddee2f1eaf64cad68a9d5c918405f642ca237c6a1ec249ff297623`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06A`: desktop generate the bounded Mesh/PBR/UV/skin/animation GLB fixture group.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the freshness protocol, generator/checker, freshness artifacts, unit test, App imports/route
|
||||
gate, manifest, and this status entry. Restore M12-05E as the queue tail and move the machine queue
|
||||
back to `M12-05F`. No parity ledger rollback is required.
|
||||
59
docs/status/M12-06A.md
Normal file
59
docs/status/M12-06A.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# M12-06A Status
|
||||
|
||||
status: done
|
||||
task: generate the bounded Mesh/PBR/UV/skin/animation GLB fixture group on desktop
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The pinned Blender 5.2.0 LTS desktop runtime generates five independent GLB 2.0 fixtures: mesh,
|
||||
PBR, UV texture, two-joint skin, and object animation. Each file has one bounded triangle primitive,
|
||||
uses no required or optional glTF extension, and remains below the 512 KiB per-file budget. The
|
||||
fixtures isolate feature ownership so later Web import comparisons cannot hide one unsupported
|
||||
domain behind an all-in-one scene.
|
||||
|
||||
The canonical report records runtime identity, file bytes and SHA-256, nodes, topology accessors,
|
||||
attributes, materials, textures/images, skins, and animations. The checker binds the M12-05F parent
|
||||
manifest and the pinned M12-05A Blender binary identity, regenerates all five files in a fresh
|
||||
temporary directory, and requires both the semantic report and every GLB byte to match exactly.
|
||||
This enabling task does not claim Web import, `.blend` save/reopen, export loss reporting, or GLB
|
||||
round-trip parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-glb-desktop-fixtures.mjs` passed: 5 fixtures, 8,676 aggregate bytes,
|
||||
Mesh/PBR/UV/skin/animation assertions, exact report regeneration, and exact GLB regeneration.
|
||||
- Mesh exports indexed triangles with POSITION/NORMAL/COLOR_0; UV exports TEXCOORD_0 plus one
|
||||
embedded PNG; skin exports JOINTS_0/WEIGHTS_0 and two inverse-bind matrices; animation exports
|
||||
translation and rotation channels sampled over 25 frames.
|
||||
- The runtime binary SHA-256 is
|
||||
`d4483926610484ef9c2ad9241aae1469f934d955ebe791f1920e263e0ba85b82`, matching M12-05A.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run test:status-consistency`, and
|
||||
`git diff --check` passed. The package hash remains the frozen
|
||||
`cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `63e1506801ddee2f1eaf64cad68a9d5c918405f642ca237c6a1ec249ff297623`
|
||||
- generator: `0247dd2405a68b42d99c2b005546ad2aa99b46416e3fe9489832467f6ea4eb4d`
|
||||
- checker: `211ebdb66bf2e2d349455d5303e889a4a1ae3323639a89dd78b3bda574dd820b`
|
||||
- desktop report: `dea31cc861622166dc502b333bc177b70b66b54d9c62aaccc6522745dab5ae13`
|
||||
- mesh GLB: `e52b9268b6524744fb498691f976000635e544ba3b47e9f8ff22b03bcdf17a94`
|
||||
- PBR GLB: `244cc8a992c5a70692b8bbc8333533718b3bac7022110715ce3b23d2e4c0b361`
|
||||
- UV GLB: `1e0397d2b69d8261b3252451b50ab4aba6525b94713719f35069a9a9d96fcfa2`
|
||||
- skin GLB: `4086ee4c8873aa03090338b676575b7a5335fb7c9384fec6ccb36108e71929f6`
|
||||
- animation GLB: `44f6cc47961a146dc97ea337ae31a8b64bb4ab213b716f81ec22129db704f1fb`
|
||||
- manifest: `e3554a1e739cbe3f217f6169130532365538b0c0eafbb97afc58d4d56c4287cb`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06B`: import the desktop GLB fixture group on Web and compare topology, attributes, materials,
|
||||
nodes, and animations.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the desktop fixture generator/checker, five GLB files, report, manifest, and this status
|
||||
entry. Restore M12-05F as the queue tail and move the machine queue back to `M12-06A`. No parity
|
||||
ledger rollback is required.
|
||||
57
docs/status/M12-06B.md
Normal file
57
docs/status/M12-06B.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# M12-06B Status
|
||||
|
||||
status: done
|
||||
task: compare desktop GLB topology, attributes, materials, nodes, and animations in Web
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production TypeScript GLB parser now exposes a canonical bounded semantic surface for the five
|
||||
M12-06A desktop fixtures. It validates referenced accessors, nodes, materials, textures, skins, and
|
||||
animation samplers before returning primitive topology, sorted attributes, PBR material fields,
|
||||
node hierarchy/TRS, skin bindings, and animation channels. A field-level comparator checks that Web
|
||||
semantics exactly match the pinned Blender 5.2 desktop report.
|
||||
|
||||
Both Node and a real Chromium Worker consume the exact committed GLB bytes and verify each source
|
||||
SHA-256 before comparing all five domains. The existing summary import API remains compatible. This
|
||||
task does not create Blender Main data or expose GLB in the file picker; the runtime route remains
|
||||
`BLOCKED_UNTIL_MAIN_PERSISTENCE` until M12-06C proves save/reopen and stable IDs.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-desktop-import.test.mjs` passed 3/3: five exact fixture imports,
|
||||
separate domain assertions, and a stable field-level PBR mismatch.
|
||||
- `node tools/web/check-glb-desktop-import.mjs` passed: 5 fixtures, 5 compared domains, exact
|
||||
desktop/Web canonical hashes, deterministic report regeneration, and the blocked route state.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5425 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-desktop-import.spec.ts` passed 1/1 from
|
||||
the `web/` directory using Chrome 150. The Worker verified source SHA-256 and all five semantic
|
||||
comparisons.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run test:status-consistency`, and
|
||||
`git diff --check` passed. The package hash remains
|
||||
`cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `e3554a1e739cbe3f217f6169130532365538b0c0eafbb97afc58d4d56c4287cb`
|
||||
- protocol: `45d9a7912c4a59a552789a8ea0dfaff5f1849f8d213f14d238de024b77acdb0d`
|
||||
- generator: `6f97527b7da04c7b4f9b09c48b9f367d1270db9f7820498d33832a80754436c2`
|
||||
- checker: `804a4b5545d95d7ab1ba265469a981d0a10b71dab36f0c96283eb73b401443d2`
|
||||
- unit: `6bf2a96b3e43e5fae93589ea5dcf98e7a69b10266378e442988198925286a8d8`
|
||||
- Chromium Worker: `eb32049631113270fb62acb7ae9379e8ff9a03e38086db2fa309c6891cd707bf`
|
||||
- Chromium test: `fa3e06419c918406f24b5a4260523bd94cfe729a84786e9434517fdfed624d45`
|
||||
- Web import report: `79933888cc5aa2d1e3639ec349ca4c31d028fe89f751ebb8d4342f06d15ecfc2`
|
||||
- manifest: `5275310394b34726a05b30ab67658e1381662dddf9163a97cb02f47f646a8fa4`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06C`: create authoritative Main data from the imported GLB, save `.blend`, reopen it, and
|
||||
compare stable IDs.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the canonical Web import surface, report generator/checker, Node/Chromium tests, report,
|
||||
manifest, and this status entry. Restore M12-06A as the queue tail and move the machine queue back to
|
||||
`M12-06B`. No parity ledger rollback is required.
|
||||
59
docs/status/M12-06C.md
Normal file
59
docs/status/M12-06C.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# M12-06C Status
|
||||
|
||||
status: done
|
||||
task: import desktop GLB results into authoritative Main, save `.blend`, reopen, and compare stable IDs
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The pinned Blender 5.2 desktop runtime imports each M12-06A GLB fixture and saves a `.blend`; the
|
||||
generator reopens every saved file and requires the complete stable Object/Mesh/Material/Image/
|
||||
Armature/Action ID set to remain unchanged. Chromium then opens those authoritative Main fixtures
|
||||
through the production WebEngine, applies one Main-owned visibility edit, saves the resulting
|
||||
`.blend`, reopens it in a fresh isolated open transaction, and compares the stable IDs with the
|
||||
desktop baseline. The saved edit is checked after reopen and the open resource counters are zero for
|
||||
input, staging, and active requests.
|
||||
|
||||
This task does not expose GLB in the normal `.blend` file picker, claim arbitrary glTF extensions,
|
||||
or change the N-023 full-parity ledger. M12-06B remains the bounded Web GLB semantic parser and
|
||||
M12-06D owns export loss reporting.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-glb-main-persistence.mjs` passed the parent manifest, all artifact hashes,
|
||||
five desktop GLB/Main fixture bindings, stable-ID shape checks, and a fresh Blender regeneration
|
||||
with exact semantic report/stable-ID comparison.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5437 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-main-persistence.spec.ts` passed 1/1.
|
||||
Every fixture opened in the production WebEngine, performed one authoritative visibility edit,
|
||||
serialized a changed `.blend`, reopened it, preserved all stable IDs, restored visibility=false,
|
||||
and returned zero active requests/input/staging resources.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. The existing package manifest was
|
||||
left unchanged so prior M12 evidence remains bound to its frozen package hash.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `5275310394b34726a05b30ab67658e1381662dddf9163a97cb02f47f646a8fa4`
|
||||
- generator: `8989d6ce4196f140a7bfb44b863dc530a6aa462ca4a57fa7b77c468e06ab61ad`
|
||||
- checker: `5bbbbeaf2d20ff9bbdeb74c8dd10fa6ffc421d1d59f86540e95f29c2cfd10903`
|
||||
- desktop report: `76b000454a9073ef762d25fa546d5c65a004659a93eb6ec82fad1e679b2e81be`
|
||||
- Chromium test: `7c97877f1cbbfd0166e106c80faee53f474f78816cca68ea924df5aa3c47776d`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- mesh `.blend`: `66e29adc016f07e220019b6f24eb7e5016c684dca4b3102b20c8e836968d422d`
|
||||
- PBR `.blend`: `ba08aeb2876d82ddf731abe81d3a42041a1be36617d0b6324c870d5bcd4cc771`
|
||||
- UV `.blend`: `1270cb452d34d2fd7a19181a2b20f70b7a028bdd2db7cf1bba4e1003f7de0f48`
|
||||
- skin `.blend`: `23f175e44ec588c75db99d3f9134863fc3d7d1f192bbd815d5d1c4e3218bce0c`
|
||||
- animation `.blend`: `fa6baf3a67ff11fe3d2922210089a7c508e4ee28bfaabe4cf628ba6addee1ff5`
|
||||
- manifest: `e3a57636a47591e3b02dff5a07e8a0aec5e0dc43bf6b4829bffc811035dbbb31`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06D`: Web export generates a machine loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M12-06C generator/checker, manifest, desktop Main fixtures, report, Chromium test, and
|
||||
this status entry. Restore M12-06B as the queue tail and move the machine queue back to M12-06C. No
|
||||
parity ledger rollback is required.
|
||||
56
docs/status/M12-06D.md
Normal file
56
docs/status/M12-06D.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# M12-06D Status
|
||||
|
||||
status: done
|
||||
task: Web GLB export generates a machine-readable loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production GLB exporter now has a schema-1 deterministic loss-report wrapper. It records the
|
||||
source SceneIR identity/revision, exportability, error/warning counts, sorted loss entries and the
|
||||
bounded data-block surface. Chromium opens all five M12-06C authoritative Main fixtures and sends
|
||||
their real snapshot/geometry/packed assets through the production exporter Worker. Exportable
|
||||
PBR/UV/skin/animation outputs are byte-hashed; the mesh fixture's unsupported Color Attribute
|
||||
shader is reported as `SHADER_GRAPH_UNMAPPABLE` and no GLB bytes are emitted.
|
||||
|
||||
This task reports the bounded exporter surface only. It does not claim lossless GLB round-trip,
|
||||
desktop re-import, arbitrary shader mapping, or GLB file-picker import; those remain later M12-06E/G
|
||||
tasks or explicit blockers.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-loss-report.test.mjs` passed deterministic sorting/count semantics.
|
||||
- `node tools/web/check-glb-loss-report.mjs` passed artifact hashes, parent Main fixture binding,
|
||||
deterministic loss ordering, mesh fail-closed output, and four exportable fixture output hashes.
|
||||
It reports `fixtures=5 blocked=mesh warnings=3`.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5445 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-export-loss-report.spec.ts` passed 1/1.
|
||||
The test uses `WebEngineClient` and a production module Worker, requests packed image assets,
|
||||
produces the report, and compares it byte-for-byte with the checked-in golden report.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. `web/package.json` remains
|
||||
unchanged so previous M12 package bindings stay valid.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `e3a57636a47591e3b02dff5a07e8a0aec5e0dc43bf6b4829bffc811035dbbb31`
|
||||
- export protocol: `a5d342827860a9e55b49a3bb3a196a01b1e53546325d6e594778afb9360c3125`
|
||||
- loss report protocol: `dce9c790b2f52d46efe0908ecb044d63d21b3c6c3f7d77ddb5e697b29a7a2d6e`
|
||||
- Worker: `6f6294d26fe7b717416a5dd25fe834fb4b9a2ecbe8b011395c9559a26701ec77`
|
||||
- Chromium test: `ce334b6bb5d82c133d317e916c03711029fba1c19c634dec06c06da9eddbd776`
|
||||
- checker: `a23346860fa26405b2cd24591b0ab36fea29cb561ec8c2991ecfeabcffc17ee1`
|
||||
- unit: `dfcc2d968e4e0c0cef4496bc304cb481f10d1f0dc4c76a40ea1d6e2f11b6b708`
|
||||
- web loss report: `c6db52234d867985ef5fbcdc7c62298ec9aaa013028b5a54e2b9a16aa4133397`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `c01c5861d493e1f177e8cde3038bc5283a7671fa39bf84484662d307623325a2`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06E`: desktop Blender re-imports Web GLB and compares the canonical report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the loss-report protocol/Worker, checker, manifest, golden report, Chromium test, and this
|
||||
status entry. Restore M12-06C as the queue tail and move the machine queue back to M12-06D. No parity
|
||||
ledger rollback is required.
|
||||
55
docs/status/M12-06E.md
Normal file
55
docs/status/M12-06E.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# M12-06E Status
|
||||
|
||||
status: done
|
||||
task: desktop Blender re-imports Web GLB and compares canonical report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The four Web GLBs that produced bytes in M12-06D (PBR, UV, skin and animation) are re-imported by
|
||||
the pinned Blender 5.2 desktop runtime, saved as `.blend`, reopened, and emitted as canonical graph
|
||||
reports. The checker binds each Web output hash to the M12-06D report and compares Object/Mesh/
|
||||
Material/Image/Armature/Action graph fields against the M12-06C desktop-import baseline.
|
||||
|
||||
PBR and animation are exact. UV records four explicit differences (corner-expanded vertex topology
|
||||
and Blender's generated texture Mix node); skin records 31 explicit differences (the exporter emits
|
||||
an additional armature helper mesh and Blender's re-import tessellation changes). These are recorded
|
||||
machine mismatches, not silently treated as parity. The N-023 parity ledger remains blocked and this
|
||||
task does not claim lossless GLB round-trip.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-glb-web-reimport.mjs` passed artifact hashes, four Web GLB source bindings,
|
||||
pinned Blender regeneration determinism, save/reopen stability, and canonical comparison. Output:
|
||||
`glb-web-reimport-ok fixtures=4 exact=2 mismatched=uv,skin deterministic=true next=M12-06F`.
|
||||
- The report binds Web GLB hashes `pbr=1ab793...`, `uv=8bd045...`, `skin=4a45d0...` and
|
||||
`animation=b83de1...`; exact/mismatch counts are fixed at PBR 0, UV 4, skin 31, animation 0.
|
||||
- The Web export Chromium test that produced the inputs passed 1/1; the desktop generator performs
|
||||
a fresh Blender import/save/reopen for every input. `npm --prefix web run typecheck` and
|
||||
`git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `c01c5861d493e1f177e8cde3038bc5283a7671fa39bf84484662d307623325a2`
|
||||
- generator: `3ae1ba45e15cae5d0308fc3fcb3766764cd374c096e27eaaddba9228a3d75004`
|
||||
- checker: `c21b45a975ec70586da1b9e50b8cf4ccf74644300b4f381c3fee0ad735cfcdb9`
|
||||
- desktop report: `e4d03d25cfac3c4beff4d0af0769b1c39b058670c679c12f4a11ae30d2d91f3c`
|
||||
- Web export test: `ce334b6bb5d82c133d317e916c03711029fba1c19c634dec06c06da9eddbd776`
|
||||
- PBR Web GLB: `1ab7936fae6e0c28e1b90e8a6ae24b3893c075c9fc58ac8896f780fdefb8277e`
|
||||
- UV Web GLB: `8bd045388527ddad7cf886c0c7a2a45b6e7d6db603568a10a959bc6d423ae145`
|
||||
- skin Web GLB: `4a45d00dfa23638682bb61a4f74b283bcd986126da4890d068902e3c85efc332`
|
||||
- animation Web GLB: `b83de103df3f5a49487868f3ede3046875c90b0d084bbd998511c3a7c987a4fa`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `3d3b13fd54a314fd6f6907fc2d314e66ef74e8ca770a8accd823370d272737fc`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06F`: sparse accessor, Draco/extension, external URI and over-budget negative cases.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the desktop Web re-import generator/checker, manifest, report, four Web GLB fixtures, and
|
||||
this status entry. Restore M12-06D as the queue tail and move the machine queue back to M12-06E. No
|
||||
parity ledger rollback is required.
|
||||
49
docs/status/M12-06F.md
Normal file
49
docs/status/M12-06F.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-06F Status
|
||||
|
||||
status: done
|
||||
task: GLB sparse accessor, extension, external URI and over-budget negative cases
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The bounded GLB importer now enforces a 512 KiB input budget, JSON/table budgets, rejects sparse
|
||||
accessors, rejects all extensions outside the pinned allowlist (currently empty), and blocks external
|
||||
buffer/image URIs. Errors are stable and fail before semantic/Main publication:
|
||||
`GLB_SPARSE_ACCESSOR_UNSUPPORTED`, `GLB_EXTENSION_UNSUPPORTED`, `GLB_EXTERNAL_URI_BLOCKED`, and
|
||||
`GLB_IMPORT_BUDGET_EXCEEDED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-negative-cases.test.mjs` passed 2/2 for sparse, extension, external
|
||||
URI, byte-budget and table-count cases.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5450 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-negative-cases.spec.ts` passed 1/1 in a
|
||||
production Chromium Worker with all four stable codes.
|
||||
- `node tools/web/check-glb-negative-cases.mjs` passed the schema-1 negative report and artifact
|
||||
hashes: `glb-negative-cases-ok cases=4 budget=524288 deterministic=true next=M12-06G`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. The package manifest remains
|
||||
unchanged.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `3d3b13fd54a314fd6f6907fc2d314e66ef74e8ca770a8accd823370d272737fc`
|
||||
- protocol: `0b6329c08e6f3cd9af6f27ef7c463b037a7cab94192afb4538d3d6c4cfcbc147`
|
||||
- unit: `9af1c155143a0c685a62f569f705afd9fcc3bb49e0d724ebf3ad2c6356d63d6d`
|
||||
- Worker: `d84a6b884ce1bfedd598b2602d803493bf10f6ad62fdfac49d64fca3f30f3931`
|
||||
- Chromium test: `c6694689ce04ff2faea2c20be648f438a9f7eb25cdfd2f714b94c1f556ea1510`
|
||||
- checker: `08377c306fd7d1082f7fd734e37809960c9798d29d626681fe9ad3f94cb7a29e`
|
||||
- negative report: `7367a624b562a9613b4b908c894ab04c731ae0a348a3b58689075f4a9decd90c`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `27b42da0683dab11a884553440088c30cf58d51364268fdaac86668786aaedd4`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-06G`: import/export cancellation, Worker restart and OPFS quota recovery.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the GLB negative-case budget/protocol changes, Worker, tests, checker, report, manifest, and
|
||||
this status entry. Restore M12-06E as the queue tail and move the machine queue back to M12-06F. No
|
||||
parity ledger rollback is required.
|
||||
57
docs/status/M12-06G.md
Normal file
57
docs/status/M12-06G.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# M12-06G Status
|
||||
|
||||
status: done
|
||||
task: GLB import/export cancellation, Worker restart, and OPFS quota recovery
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Schema-1 GLB recovery receipts now bind operation, worker generation, source/output SHA-256,
|
||||
revision, temporary bytes, live requests, commit state, and stable cancellation/restart/quota codes.
|
||||
Both import and export cancellation release all temporary bytes and publish no result. A new Worker
|
||||
repeats the same bounded GLB import with an identical semantic result hash.
|
||||
|
||||
The GLB asset persistence path uses the existing content-addressed OPFS store. A real Chromium
|
||||
origin quota of 64 KiB rejects a 128 KiB candidate, while the previously committed GLB remains
|
||||
readable after Storage Worker restart. Raising the quota allows a small follow-up asset to commit.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/glb-recovery.test.mjs` passed 2/2 for cancel, quota, commit, and
|
||||
generation transition invariants.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5455 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/glb-recovery.spec.ts` passed 2/2 in Chrome
|
||||
150. The first real-quota run reached the expected browser failure but the assertion only accepted
|
||||
the injected error wording; the final run accepts both native and injected quota messages.
|
||||
- `node tools/web/check-glb-recovery.mjs` passed with
|
||||
`glb-recovery-ok cancelled=2 workerGeneration=2 quota=GLB_OPFS_QUOTA smallRecovery=true next=M12-07A`.
|
||||
- `npm --prefix web run typecheck`, `node --check tools/web/check-glb-recovery.mjs`, and
|
||||
`git diff --check` passed. The package manifest remains unchanged.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `27b42da0683dab11a884553440088c30cf58d51364268fdaac86668786aaedd4`
|
||||
- recovery protocol: `da4e2a546d7598e80798cfebd105e52b7522c896acb545710c78bb8a5c3705aa`
|
||||
- storage protocol/client/Worker: `2c8ce9e32fcae973e9262a024fd849221680104bcd427ec308f99ef25112d951` /
|
||||
`00cd35e4632479e4cd153314113e201c822fd209ae6c8e9fbeff5f1399728565` /
|
||||
`80bf4d2ac59cbf7998c2a72c8961ae38abe43685b60df564d0746e1a45e9e1bc`
|
||||
- operation Worker/browser adapter: `947c4a768422725ff2f689b2eefa8068bee51bb7ff342af17e8d4a4d0a4a7ca2` /
|
||||
`2c753a04c153471c2bf7691073b836d968a1a1300e3da038f493983b46738cdf`
|
||||
- unit/Chromium: `6dd48f62a85c5aaf3a04b6e572a47a7986b23cbec84a099ea510af81e8dd3a3a` /
|
||||
`7d95e992f44fb913f70c104f0d6b23bd76f47d48db4a21899e35ae1d188e2093`
|
||||
- checker/report: `b185248fdcd6b3cee84252bd68fcb6921bb6385bfa4a00486e93c58e94755cce` /
|
||||
`1a008a76590573468446ca6e5cbdfe0ea5a8b27493291590d937b90db90d6e42`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `1c732b8d9f1a0bdb502f44e2e843e91efea12e93483a35658f8a9c70a69a2430`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07A`: OBJ single-Mesh positive fixture covering position, normal, UV, and material group.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the GLB recovery receipt, quota fault option, Worker/browser adapter, tests, checker, report,
|
||||
manifest, and this status entry. Restore M12-06F as the queue tail and move the machine queue back to
|
||||
M12-06G. No parity ledger rollback is required.
|
||||
49
docs/status/M12-07A.md
Normal file
49
docs/status/M12-07A.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-07A Status
|
||||
|
||||
status: done
|
||||
task: OBJ single-Mesh desktop positive fixture
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `WM_OT_obj_export` now generates one deterministic Wavefront OBJ object with
|
||||
four positions, four UV coordinates, one explicit normal, two triangle faces, two material records,
|
||||
and two material groups. The `.mtl` sidecar is kept beside the OBJ and both files are bound to the
|
||||
canonical semantic report. Web parsing/import, multi-object and negative cases remain queued.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-obj-single-mesh-fixture.py -- tests/files/web/m12_obj_desktop_v1
|
||||
tests/golden/M12-07A/desktop-fixture.json` completed with 4 positions, 4 UVs, 1 normal,
|
||||
2 faces, and 2 materials/groups.
|
||||
- `node tools/web/check-obj-single-mesh-fixture.mjs` passed deterministic regeneration in a fresh
|
||||
temporary directory and byte-for-byte OBJ/MTL comparison:
|
||||
`obj-single-mesh-fixture-ok vertices=4 normals=1 uv=4 faces=2 materials=2 deterministic=true next=M12-07B`.
|
||||
- Runtime identity matches the pinned M12-05A Blender 5.2 inventory; the report is anchored to
|
||||
`blender-5.2.0/source/blender/io/wavefront_obj` and `wm.obj_export`.
|
||||
- Package hash remains frozen; no Web route or parity ledger status was changed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `1c732b8d9f1a0bdb502f44e2e843e91efea12e93483a35658f8a9c70a69a2430`
|
||||
- generator: `604c3006f194c7c64a487b8f760693b66830f3cfa602928b46769955e7d4f358`
|
||||
- checker: `3d0208f61a86d4d29796d8284756f53931c90864b15b7dfe4fcc84d7f65a8040`
|
||||
- desktop report: `6c560a8eecf84973c2b05f9fd50d33bd45515e97c4f7970f1502de406c39f6a5`
|
||||
- OBJ/MTL: `a56694d1ee28735c68381ff18c3a52581612feebac0101a53e502956c27d144f` /
|
||||
`392f1b10ff5a0b142d520a9443b4c96191985f15d4244c79b36fdeda0f153715`
|
||||
- runtime inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `d80b74502202effa7be15640c945dc7e04af703b58e7a15c3fe7babc43c17b46`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07B`: OBJ multi-object, negative-index, MTL/texture-origin, and malformed-face cases.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the OBJ generator, checker, desktop report, OBJ/MTL fixture, manifest, and this status entry.
|
||||
Restore M12-06G as the queue tail and move the machine queue back to M12-07A. No parity ledger rollback
|
||||
is required.
|
||||
53
docs/status/M12-07B.md
Normal file
53
docs/status/M12-07B.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# M12-07B Status
|
||||
|
||||
status: done
|
||||
task: OBJ multi-object, negative-index, texture-origin, and malformed-face fixtures
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `wm.obj_export` now produces a two-object OBJ/MTL positive fixture with two
|
||||
relative `map_Kd` references and a 2x2 PNG texture. The deterministic generator derives a negative
|
||||
index OBJ variant and a malformed two-vertex face variant from the same positive bytes. The report
|
||||
keeps multi-object/group/material counts and expected fail-closed `OBJ_FACE_ARITY_INVALID` separate;
|
||||
it does not claim that a Web parser or OBJ import route exists.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-obj-multi-negative-fixtures.py -- tests/files/web/m12_obj_multi_v1
|
||||
tests/golden/M12-07B/desktop-fixtures.json` completed with 2 objects, 6 positions, 6 UVs,
|
||||
2 normals, 2 faces, 2 materials, relative `m12_obj_texture.png`, and both derived variants.
|
||||
- `node tools/web/check-obj-multi-negative-fixtures.mjs` passed fresh-directory Blender regeneration,
|
||||
exact OBJ/MTL/PNG/negative/malformed bytes, negative-index acceptance shape, malformed-face arity,
|
||||
and PNG signature checks:
|
||||
`obj-multi-negative-fixtures-ok objects=2 negative=true malformed=OBJ_FACE_ARITY_INVALID textureOrigin=relative deterministic=true next=M12-07C`.
|
||||
- Runtime identity matches M12-05A pinned Blender 5.2; no Web parser, UI route, or parity ledger
|
||||
status changed. Package hash remains frozen.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `d80b74502202effa7be15640c945dc7e04af703b58e7a15c3fe7babc43c17b46`
|
||||
- generator: `8d4faed82cba76e46bf639e5031b30568e8b9a15240cbddb1c22ee7ad11d697b`
|
||||
- checker: `61188d67efd6133e714f2d55c7c8516b9d04896de068f994523a3c398eebdd2f`
|
||||
- desktop report: `b60ff785676c0f0168588605ad442a650615191ac00770b7e5a308cc4ade83ce`
|
||||
- OBJ/MTL/PNG: `4ed3dced8445b03754cd3916ae2e8cf0dff85e6a5882f1c6f0a4a4e4c5251f6a` /
|
||||
`80338f569c67a8b1616515ba878ffc72b26e93ef2e8c361131023fb14f132f5f` /
|
||||
`44e4fd08bdda8403908349e2a62dcf103ce2d0851099fc61cd868d65ddbef78c`
|
||||
- negative/malformed OBJ: `9457954284cac1d68e23627e3ff734c0c591b3a24086ce5aa3d0dbbfc22f01bc` /
|
||||
`6dd508b5ba944c2d15e2889c9ad9a3693845145c3bf6c9bf7df992081c915864`
|
||||
- runtime inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `785f593271058098704498cb0a7c948305087f1a83bf8f29b6e6fb9fe9341926`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07C`: Web-to-desktop OBJ round-trip and loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the multi/negative OBJ generator, checker, fixtures, report, manifest, and this status entry.
|
||||
Restore M12-07A as the queue tail and move the machine queue back to M12-07B. No parity ledger rollback
|
||||
is required.
|
||||
55
docs/status/M12-07C.md
Normal file
55
docs/status/M12-07C.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# M12-07C Status
|
||||
|
||||
status: done
|
||||
task: Web-to-desktop OBJ round-trip and loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The bounded TypeScript OBJ protocol parses positive and negative indices, position/UV/normal streams,
|
||||
objects/groups/faces, MTL `map_Kd`, and stable budgets; it serializes a deterministic Web OBJ/MTL pair
|
||||
and emits a machine loss report for unbound texture origins. A Chromium Worker consumes the M12-07B
|
||||
double-object fixture, then a new pinned Blender 5.2 process imports the Web output with split groups.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/obj-import.test.mjs` passed 3/3 for negative-index resolution,
|
||||
deterministic serialization, bound/unbound texture loss, malformed face arity, and index range.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5460 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/obj-web-roundtrip.spec.ts` passed 1/1 in Chrome
|
||||
150. Browser output has 2 objects, 6 positions/UVs, 2 normals, 2 faces, 2 materials; bound texture
|
||||
loss is zero and missing texture loss contains two `OBJ_TEXTURE_ORIGIN_UNRESOLVED` warnings.
|
||||
- The test writes the browser OBJ/MTL and texture to an isolated directory, invokes pinned Blender
|
||||
`wm.obj_import`, and compares 2 objects, 2 triangles, UVMap presence, and one material per object.
|
||||
- `node tools/web/check-obj-web-roundtrip.mjs` passed the exact golden and artifact hash gate:
|
||||
`obj-web-roundtrip-ok objects=2 triangles=2 lossWarnings=2 desktopExact=true next=M12-07D`.
|
||||
- `npm --prefix web run typecheck`, Python compile, and `git diff --check` passed. Package hash remains
|
||||
frozen; OBJ Web capability is still bounded and does not change N-023 parity.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `785f593271058098704498cb0a7c948305087f1a83bf8f29b6e6fb9fe9341926`
|
||||
- protocol: `e7240af65e0d90f3ee690a4e3f391416fe4744ac6c46edc8ac0d72386857cab9`
|
||||
- Worker: `bf1fcc60ec318cf6c2747d44f4af741b46f284cf5f5307e142f0ab6d50b14302`
|
||||
- desktop importer: `9f1eb4ab679255a0f1f596696e8befc33a4e30c0cbe6ea423e2aaa0314cec22d`
|
||||
- checker: `9d53014f4b89f786c516ebe8d300030c2728e4a36a86a5ef136b2769a12ac96b`
|
||||
- unit/Chromium: `485a669be5de8e370e9b5a3239357b028ba61ca5c4076819cd46aed52a5c210a` /
|
||||
`93785b4017ba14b007926b0f82442f8ae5968f242a2a762e5f5dc77d36110f5b`
|
||||
- report: `45eaffc9c2e50c84b557d13ebbe9f4f53b63e19e00bc69b272491ef6366dff81`
|
||||
- fixture OBJ/MTL/PNG: `4ed3dced8445b03754cd3916ae2e8cf0dff85e6a5882f1c6f0a4a4e4c5251f6a` /
|
||||
`80338f569c67a8b1616515ba878ffc72b26e93ef2e8c361131023fb14f132f5f` /
|
||||
`44e4fd08bdda8403908349e2a62dcf103ce2d0851099fc61cd868d65ddbef78c`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `0c639954900b1fcc3b8285d0f4c0ecfa5807df6cde6d1f2cd3b59c4636d71674`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07D`: split STL binary and ASCII capability declarations.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the OBJ protocol, Worker, desktop importer, unit/E2E tests, checker, report, manifest, and this
|
||||
status entry. Restore M12-07B as the queue tail and move the machine queue back to M12-07C. No parity
|
||||
ledger rollback is required.
|
||||
47
docs/status/M12-07D.md
Normal file
47
docs/status/M12-07D.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# M12-07D Status
|
||||
|
||||
status: done
|
||||
task: split STL binary and ASCII capability declarations
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `WM_OT_stl_export` now generates binary and ASCII STL from the same selected
|
||||
two-triangle mesh using identical axis, scale, unit, evaluation, and modifier settings. The report
|
||||
keeps `STL_BINARY/ascii_format=false` and `STL_ASCII/ascii_format=true` as separate variants; it does
|
||||
not infer the format from the `.stl` extension or claim Web parsing/import support.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-stl-capability-fixtures.py -- tests/files/web/m12_stl_capability_v1
|
||||
tests/golden/M12-07D/capability-report.json` generated a 184-byte binary STL with two 50-byte
|
||||
triangle records and a 213-byte ASCII STL with two facets/six vertex lines.
|
||||
- `node tools/web/check-stl-capability-fixtures.mjs` matched runtime identity to M12-05A, validated
|
||||
both independent encodings, regenerated the report/files byte-for-byte in a fresh directory, and
|
||||
returned `stl-capability-fixtures-ok binaryTriangles=2 asciiFacets=2 deterministic=true next=M12-07E`.
|
||||
- Package hash remains frozen. This enabling task does not change N-023 parity or expose an STL UI
|
||||
route.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `0c639954900b1fcc3b8285d0f4c0ecfa5807df6cde6d1f2cd3b59c4636d71674`
|
||||
- generator: `8310104e66f246b32ac7cb4619e7f4da109baf2ece39ea670cbb6d33bd88c8b8`
|
||||
- checker: `b2ad901eaa9701436cf7bcc8aa4e40d1b2d6eda7c6c44a0af830347a37cc9ca8`
|
||||
- desktop report: `29c7d2a6e6764440c99eec25bb5760c7e0880839691757fb3e607ed4f5050013`
|
||||
- binary/ASCII fixtures: `50161172cd12e4240067064db6f80e74b2df69c475e3e34154e9d0523928c1ca` /
|
||||
`a463a5add8be070fb67b34f00ef6e7b46025aed31fa429d4a033d75a11cf0113`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `bbc78e47f389562e7d648bf49c9b3bf8a08aaa36e914589a6eab0a1f6e72748d`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07E`: STL normal, unit, degenerate-triangle, and trailing-byte parity.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the STL capability generator, checker, fixtures, report, manifest, and this status entry.
|
||||
Restore M12-07C as the queue tail and move the machine queue back to M12-07D. No parity ledger rollback
|
||||
is required.
|
||||
60
docs/status/M12-07E.md
Normal file
60
docs/status/M12-07E.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# M12-07E Status
|
||||
|
||||
status: done
|
||||
task: STL normal, unit, degenerate-triangle, and trailing-byte parity
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The bounded STL protocol requires an explicit binary/ASCII variant and positive unit scale. It parses
|
||||
facet normals and vertices, applies the scale, removes zero-area triangles the same way as Blender's
|
||||
validated import, and rejects binary payload after the declared triangle table with
|
||||
`STL_TRAILING_BYTES`. Desktop Blender accepts that trailing fixture as an empty mesh, so the report
|
||||
records `STRICTER_WEB_BLOCK` rather than claiming exact parity for that edge case.
|
||||
|
||||
## Evidence
|
||||
|
||||
- The deterministic edge generator derived a one-degenerate-triangle binary and a four-trailing-byte
|
||||
binary from M12-07D. Pinned Blender 5.2 was probed at unit scales 1 and 0.001 and against both edge
|
||||
files; it preserves normals, scales world bounds by 1000, removes one degenerate triangle, and
|
||||
accepts the trailing fixture as an empty mesh.
|
||||
- `node --test web/tests/unit/stl-import.test.mjs` passed 2/2 for binary/ASCII normals, explicit unit
|
||||
scaling, degenerate removal, trailing-byte rejection, and invalid scale.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5463 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/stl-edge-parity.spec.ts` passed 1/1 in Chrome
|
||||
150. Normal comparison is exact, Web/Desktop unit ratio matches within Float32 tolerance, and both
|
||||
retain one triangle after degenerate removal.
|
||||
- `node tools/web/check-stl-edge-parity.mjs` passed:
|
||||
`stl-edge-parity-ok normals=exact unitRatio=1000 degenerate=removed trailing=STRICTER_WEB_BLOCK next=M12-07F`.
|
||||
- Typecheck and `git diff --check` passed. The stricter trailing-byte policy leaves N-023 full parity
|
||||
blocked and does not expose an STL UI route.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `bbc78e47f389562e7d648bf49c9b3bf8a08aaa36e914589a6eab0a1f6e72748d`
|
||||
- fixture generator/desktop probe: `018013347642603c21237ebb023bdc7a4e338f5a3f875fea536a996eb121e716` /
|
||||
`b3d6ea197ef77b5a14f60f5e6b43d4392e943ff5d56acf73915507fc9a4161b7`
|
||||
- protocol/Worker: `87eec72e2b8aa7ad0b168ca0ee8c4016c941f56f5f1ac53aa5fe71d0832f1dd8` /
|
||||
`d714f1f3a218a2226dd349aea81c6c54efa6246de1c4fe51aaa9f5c352ef44fc`
|
||||
- unit/Chromium/checker: `4af52833486421c017f3af2b833b0776e60a6ab57ed66fea2161cf9674f4b243` /
|
||||
`121d348250e26d29ad966f7427bbef9da77de2098e2e305827b11aae52002c5c` /
|
||||
`b5ed7fbb41bb46fba982d5726cb8c3eaecf360b772a01d6337c309b1c4a4f535`
|
||||
- fixture/desktop/Web reports: `545463a984356d6635cbaae3865d13fe95bd2d841c394ac9ddff496c95d46f18` /
|
||||
`2d3028a3b7d97f39654cff5fcef1d0c1c71e9f2d08e3e29c2e926651ed3860f1` /
|
||||
`e0686cc9be3b68e564651207443e0ebf3e3b0eb3d07a32915b03f44b1908357b`
|
||||
- degenerate/trailing fixtures: `c120bb0f218819eb89a3607c0b4f8fafd9afb599402e3b21deaa3b2be143e7d0` /
|
||||
`0a30aab6db1588722067000e2a08c3c6206a8ed5b7531caa0b082723700a3681`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `19a9f460d1b939c9504dadd364cb87dab3b1769b0599035e2d2b51b47091e034`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07F`: STL Web-to-desktop round-trip and material-loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the STL edge fixtures, probes, parser, Worker, tests, reports, checker, manifest, and this status
|
||||
entry. Restore M12-07D as the queue tail and move the machine queue back to M12-07E. No parity ledger
|
||||
rollback is required.
|
||||
51
docs/status/M12-07F.md
Normal file
51
docs/status/M12-07F.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# M12-07F Status
|
||||
|
||||
status: done
|
||||
task: STL Web-to-desktop round-trip and material-loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The STL Web path now serializes the bounded parsed triangle result back to deterministic binary STL.
|
||||
The loss report explicitly records STL's lack of material slots as
|
||||
`STL_MATERIAL_UNSUPPORTED`; it never silently claims material preservation. A Chromium Worker output
|
||||
is imported by a fresh pinned Blender 5.2 process and compared by triangle count and facet normals.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/stl-export.test.mjs` passed 1/1 for binary header/table serialization
|
||||
and explicit material-loss warning.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5467 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/stl-web-roundtrip.spec.ts` passed 1/1 in Chrome
|
||||
150. Browser output is 184 bytes/2 triangles; Blender reopens 2 polygons/2 triangles with exact
|
||||
normals; warning code is `STL_MATERIAL_UNSUPPORTED`.
|
||||
- `node tools/web/check-stl-web-roundtrip.mjs` passed:
|
||||
`stl-web-roundtrip-ok triangles=2 normals=exact materialLoss=1 desktopExact=true next=M12-07G`.
|
||||
- Typecheck and `git diff --check` passed. The STL material loss remains machine-visible and STL UI
|
||||
route/parity stays bounded.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `19a9f460d1b939c9504dadd364cb87dab3b1769b0599035e2d2b51b47091e034`
|
||||
- protocol/Worker: `3b9c409de9fb3eaea34f82c1ddd466670d2b478845d8ff6af3c4e44cb4e04a52` /
|
||||
`1da8b8281cf8ebf9ccf5fd2f42da8ed5886001ab83daba8d9fcd88980257af87`
|
||||
- desktop importer: `c4cbff52ff2e7cecba7aeab47e865975955da23a0e1e8ff885ece56b894558d5`
|
||||
- unit/Chromium/checker: `f06af242df80ec26d06e92b749449cfebaf909476198ff825207cdd4b9484102` /
|
||||
`2e979dcd030f5316fcbe28e2c19b1c99fe5d111e849d3fc1d2ea316d2159032b` /
|
||||
`093de04bf80b0909eee56ea590e04e7aa4749168e2e49615c62ab39ddc0d16cf`
|
||||
- report: `0495c645b4280f6e7821f0ba02010e25d4accbc552e3cd7c58e052607799040e`
|
||||
- source fixture: `50161172cd12e4240067064db6f80e74b2df69c475e3e34154e9d0523928c1ca`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `3cbbcb541ee123da0ef8916ac2ca8805680d539bbf8db3b4a8d331aec418148c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07G`: PLY ASCII/binary little-endian capability declarations.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the STL export/loss protocol, Worker, desktop importer, tests, checker, report, manifest, and
|
||||
this status entry. Restore M12-07E as the queue tail and move the machine queue back to M12-07F. No
|
||||
parity ledger rollback is required.
|
||||
53
docs/status/M12-07G.md
Normal file
53
docs/status/M12-07G.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# M12-07G Status
|
||||
|
||||
status: done
|
||||
task: PLY ASCII and binary little-endian capability declarations
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 `WM_OT_ply_export` now has two independently declared capability variants for
|
||||
the same selected two-triangle mesh: `PLY_ASCII` and `PLY_BINARY_LITTLE_ENDIAN`. The report binds
|
||||
the export settings, source/operator anchor, runtime identity, header semantics, and byte hashes;
|
||||
the variant is never inferred from a shared `.ply` extension. This enabling task freezes desktop
|
||||
capability only and does not expose a Web PLY parser or import route.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-ply-capability-fixtures.py -- tests/files/web/m12_ply_capability_v1
|
||||
tests/golden/M12-07G/capability-report.json` generated an ASCII PLY with four vertices/two faces
|
||||
and a binary little-endian PLY with the same four vertices/two faces. Both headers explicitly carry
|
||||
their independent encoding declarations and Blender export settings are recorded in the report.
|
||||
- `node tools/web/check-ply-capability-fixtures.mjs` matched every runtime identity field to the
|
||||
pinned M12-05A inventory, validated the `ascii` and `binary_little_endian` variants, checked the
|
||||
vertex/face element counts and artifact hashes, regenerated both files in a fresh temporary
|
||||
directory, and passed byte-for-byte determinism:
|
||||
`ply-capability-fixtures-ok ascii=ascii binary=binary_little_endian vertices=4 faces=2 deterministic=true next=M12-07H`.
|
||||
- `python3 -m py_compile tools/web/generate-ply-capability-fixtures.py` and
|
||||
`node --check tools/web/check-ply-capability-fixtures.mjs` passed. The package hash remains
|
||||
frozen and N-023 parity remains blocked; no PLY Web UI route was exposed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `3cbbcb541ee123da0ef8916ac2ca8805680d539bbf8db3b4a8d331aec418148c`
|
||||
- generator: `581cd84057357e3a87997cf9c07d5d5633209648ac11e44611782eb254a38ebd`
|
||||
- checker: `5280d6e57b7a722ea881e27b792c6082c5113c1577ac0e87f87cc87fdf59516c`
|
||||
- desktop report: `26b1ce83334b41778cef5ce2a1f2c4d34254f63d7c7573cb3fb550f93ddeabb2`
|
||||
- ASCII/binary little-endian fixtures: `63646cab9bf6ccecb23092e5e24d04df1e0a690c866127c72a35791e99262331` /
|
||||
`e40fbb494b8b147c555a0fc06eb191415406bb9a6c061acf6befd8464c8c41a5`
|
||||
- runtime inventory: `0d660b0fd8b647ebbf4e91afebd5006bd100973ab8e2507a5bfe759f477b33b4`
|
||||
- package: `cfb232baa494ff59f6c8d65514a08c86332ee9354350b2a0392b6f932a7ee42c`
|
||||
- manifest: `87df9c12f9c6eacf63051b70e9bb2eb43ebd1e5c4487b3512c45adb94cbb82ea`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07H`: PLY vertex/face/color/custom-property mapping and unknown-property loss report.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the PLY capability generator, checker, fixtures, report, manifest, and this status entry.
|
||||
Restore M12-07F as the queue tail and move the machine queue back to M12-07G. No parity ledger
|
||||
rollback is required.
|
||||
62
docs/status/M12-07H.md
Normal file
62
docs/status/M12-07H.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# M12-07H Status
|
||||
|
||||
status: done
|
||||
task: PLY vertex/face/color/custom property mapping and unknown property loss report
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production `ply-import` protocol now accepts explicitly declared ASCII and binary
|
||||
little-endian PLY. Vertex position, normal, RGBA color, numeric custom properties, face
|
||||
indices, and numeric face properties are mapped into a bounded canonical document. Unsupported
|
||||
vertex/face list properties and unknown elements are skipped with deterministic
|
||||
`PLY_UNKNOWN_PROPERTY`/`PLY_UNKNOWN_ELEMENT` loss warnings; mapped fields remain available.
|
||||
The worker serializes the canonical document to bounded ASCII PLY for desktop validation.
|
||||
This task does not expose a general PLY file-picker route or claim full PLY attribute parity.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-ply-mapping-fixtures.py -- tests/files/web/m12_ply_mapping_v1
|
||||
tests/golden/M12-07H/mapping-report.json` generated deterministic ASCII and binary
|
||||
little-endian fixtures containing four vertices, two faces, RGBA colors, and two numeric
|
||||
custom vertex attributes. A derived ASCII fixture contains an unsupported list property.
|
||||
- `node tools/web/check-ply-mapping-fixtures.mjs` matched pinned Blender 5.2 runtime identity,
|
||||
artifact hashes, field counts and a fresh byte-for-byte regeneration:
|
||||
`ply-mapping-fixtures-ok vertices=4 faces=2 colors=rgba custom=2 unknown=PLY_UNKNOWN_PROPERTY deterministic=true next=M12-07I`.
|
||||
- `node --test web/tests/unit/ply-import.test.mjs` passed 3/3. It covers both encodings,
|
||||
mapped values, unknown-property loss, serialization/reopen, and format mismatch blocking.
|
||||
- `UPDATE_PLY_MAPPING_REPORT=1 CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5472
|
||||
node_modules/.bin/playwright test --config playwright.config.ts --workers=1
|
||||
tests/e2e/ply-web-roundtrip.spec.ts` passed 1/1. Production Chromium Worker parsed both
|
||||
encodings, reported unknown loss, serialized ASCII, and pinned Blender 5.2 re-imported the
|
||||
result with exact vertex/face/position counts and mapped custom/color attributes.
|
||||
- `npm --prefix web run typecheck`, `node --check tools/web/check-ply-mapping-fixtures.mjs`,
|
||||
and Python compile checks passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `058a3263fde553637840a4e9ad4e8e9d923eb52c250f8000317c7f43a228881d`
|
||||
- worker: `f6bf5e39e83286d7b257bbdce88f4d7fa027c64651da9765567788b5cf298c71`
|
||||
- generator: `ffc051eccfc6973ee00cc791cdbd641fcce308b4083741e3e6ae82291d9347b7`
|
||||
- checker: `2b055dbc705830848efdf4d8db8543a3ccc684de1f258732bcafefa86cf65c3a`
|
||||
- desktop importer: `6edbc6e401a1a902dcfd11c4d767e8c8620d694e40eb4ca29dd8479f9c55ef37`
|
||||
- unit/e2e: `b03a5f4b4b2a974fa26e653763470b92d1433c5d352ae09ab5492b841e6e5e1f` /
|
||||
`2cadebc89057655d78e9b520bb6adf9debb27c6d783cd002efee08d269636fb9`
|
||||
- desktop mapping report: `8a02fc9e364ed79e50ef00897affa9ab63808d3cb3cdabd00fdb8ee4c26ec18a`
|
||||
- Chromium/desktop round-trip report: `1ca9d3b7870fcc8c9e3c9bbbd90ef48bd13bbc9ae0462312c9482f24f05f13ec`
|
||||
- ASCII/binary/unknown fixtures: `acaa369c17252d4d089a2e3064d0c1fcdfdb2d066759ed160adf7869d3e859d5` /
|
||||
`d0fc195fd1a101c42ac984a2382bccdddb7d0bf60dd618e9f637c964f1b30b9e` /
|
||||
`a994c7126f235d0067ce4af35f8b0c6699cc83073e2a37e982edd45ece459f33`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07I`: PLY big-endian, malformed list, and oversized count stable blocking.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the PLY mapping protocol, worker, fixture generator/checker, fixtures, reports, tests,
|
||||
package script, and this status entry. Restore M12-07G as the queue tail and move the machine
|
||||
queue back to M12-07H. No parity ledger rollback is required.
|
||||
49
docs/status/M12-07I.md
Normal file
49
docs/status/M12-07I.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M12-07I Status
|
||||
|
||||
status: done
|
||||
task: PLY big-endian, malformed list, and oversized count stable blocking
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
PLY admission now fails closed for unsupported big-endian input, truncated/malformed list data,
|
||||
and element counts above the bounded 65,536 record budget. The production parser returns stable
|
||||
codes `PLY_FORMAT_UNSUPPORTED`, `PLY_DATA_TRUNCATED`, and `PLY_IMPORT_BUDGET_EXCEEDED: vertex`;
|
||||
the Worker does not publish a partial document. No big-endian route or unbounded PLY import is
|
||||
claimed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/generate-ply-negative-fixtures.mjs` generated deterministic big-endian,
|
||||
malformed-list, and oversized-count fixtures. `node tools/web/check-ply-negative-fixtures.mjs`
|
||||
regenerated them in a fresh temporary directory and passed:
|
||||
`ply-negative-fixtures-ok cases=3 bigEndian=PLY_FORMAT_UNSUPPORTED malformed=PLY_DATA_TRUNCATED oversized=PLY_IMPORT_BUDGET_EXCEEDED deterministic=true next=M12-07J`.
|
||||
- `node --test web/tests/unit/ply-negative.test.mjs` passed 2/2 for all three stable error paths.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5478 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/ply-negative.spec.ts` passed 1/1. The
|
||||
production Worker returned the exact expected error for each case and never returned `ok=true`.
|
||||
- `npm --prefix web run typecheck`, Node syntax checks, and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `058a3263fde553637840a4e9ad4e8e9d923eb52c250f8000317c7f43a228881d`
|
||||
- generator/checker: `9c09707bdfe73ba467bbfbf61ed3846fb59fd33ab5563a3a62c8032722ff6938` /
|
||||
`b1d047d4cb1fa15dff7821687e7028ad073fdc62d4c76f60a2656732c0ec5e2b`
|
||||
- unit/e2e: `60439f9e6bc221df8866956bf926816a347e85828b5a93deb26ee23015cf449a` /
|
||||
`6509a29d6842f3423d4dfcc40dbd52a959a5efa7ee1121143dce06e5bbc4a460`
|
||||
- report: `fbe2830d1b19294ea98eea66c3e00125bc0809a4bb8a750612939cbe1f5acca9`
|
||||
- fixtures: `cda92943a3690529fbb3463d328b6796ac0d07e19139450556f7411fc1f031e3` /
|
||||
`a6a576b7a04d919b540520a6f43a89c089f0d706a17fd8b390711fff6b8b03df` /
|
||||
`fcd99e0838025429420a47466251cf80e638d2b5816ad14d5aa696364525bb`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M12-07J`: three-format cancellation, OOM, Worker restart, and small-file recovery.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the count guard, negative fixture generator/checker, fixtures, report, tests, manifest,
|
||||
and this status entry. Restore M12-07H as the queue tail and move the machine queue back to
|
||||
M12-07I. No parity ledger rollback is required.
|
||||
50
docs/status/M12-07J.md
Normal file
50
docs/status/M12-07J.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# M12-07J Status
|
||||
|
||||
status: done
|
||||
task: three-format cancellation, OOM, Worker restart, and small-file recovery
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
OBJ, STL, and PLY now share a schema-1 recovery receipt. Each bounded production Worker run
|
||||
binds format, input hash, base/candidate revision, Worker generation, output hash, temporary bytes,
|
||||
live requests, published result count, and commit state. Cancellation clears temporary state and
|
||||
publishes no result; over-budget/OOM input returns `IO_FORMAT_OOM`; a generation-2 rerun and a
|
||||
generation-3 small-file run reproduce the generation-1 output hash. This is recovery evidence for
|
||||
the bounded format workers, not a general file-picker or full Blender IO claim.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/io-format-recovery.test.mjs` passed 2/2 for cancellation/OOM cleanup,
|
||||
commit identity, generation recovery, and stale-generation blocking.
|
||||
- `UPDATE_IO_FORMAT_RECOVERY_REPORT=1 CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5492
|
||||
node_modules/.bin/playwright test --config playwright.config.ts --workers=1
|
||||
tests/e2e/io-format-recovery.spec.ts` passed 1/1. The report covers OBJ, STL, and PLY separately:
|
||||
three cancellations, three OOM budget faults, three Worker-generation restarts, and three small
|
||||
recovery commits; all output SHA-256 values are stable.
|
||||
- A second run without report update passed against the same golden, proving deterministic operation
|
||||
IDs and receipt output. `node tools/web/check-io-format-recovery.mjs` passed:
|
||||
`io-format-recovery-ok formats=OBJ,STL,PLY cancelled=3 oom=3 restart=3 smallRecovery=3 deterministic=true next=M13-01A`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `7e352539e3300969c7409c34d6056eb6ad31055431ffce84b1b0a459c335480a`
|
||||
- worker/testing adapter: `63b78fbf25132cad28147ef68731f2cd212a26c96b464fdec349a13ebaa1174f` /
|
||||
`cfcebb6ec38936a66983957b0dede716871cfbfbea3cb53cddc16f3e24fb19b0`
|
||||
- unit/e2e: `aaed1f2abe4789b084c8a6a60bcce8595d38220d7e6678a93924cd05c5716b4f` /
|
||||
`5c1750fa408e1297fc43f2e5749be3e9ac08a16b86265d22f0f06053f52b3bd7`
|
||||
- checker: `6ef6bc4a168f8675a4933a06c296f61076b9ea64cec25b295e961a9b610ab1a2`
|
||||
- report: `35d4fe10d8a4fa84d6e05a85f20ca50975d93a86df41e73c7bbc5875edc4fc70`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01A`: begin the next machine-queued milestone task.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the IO recovery protocol, worker, adapter, tests, checker, report, manifest, and this
|
||||
status entry. Restore M12-07I as the queue tail and move the machine queue back to M12-07J. No
|
||||
parity ledger rollback is required.
|
||||
47
docs/status/M13-01A.md
Normal file
47
docs/status/M13-01A.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# M13-01A Status
|
||||
|
||||
status: done
|
||||
task: inventory Text, Python Console, autorun, driver expression, handler, and add-on entry points
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: true
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 now has a machine-readable scripting entry inventory covering three Text
|
||||
datablocks, Python Console operators, a module-autorun request, one driver expression, 39 handler
|
||||
groups, and four add-on operators. The report records the entry source and default Web policy:
|
||||
Text is metadata-only, while Console, autorun, driver expressions, handlers, and add-on operations
|
||||
are `DENY`. This task only inventories entry points; it does not execute script text or open a
|
||||
browser scripting route.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-script-entry-inventory.py -- tests/files/web/m13_script_entry_v1
|
||||
tests/golden/M13-01A/entry-inventory.json` created a fixture with internal/external Text,
|
||||
`use_module` autorun metadata, and a driver expression without executing user code.
|
||||
- `node tools/web/check-script-entry-inventory.mjs` matched pinned runtime identity, policy and
|
||||
semantic inventory, then regenerated the report in a fresh directory. Blender's `.blend` save
|
||||
contains runtime save bytes that may differ between runs, so determinism is asserted on the
|
||||
inventory and fixture byte length; the checked-in fixture hash remains bound in the manifest.
|
||||
Output: `script-entry-inventory-ok texts=3 console=3 autorun=1 drivers=1 handlers=39 addonOps=4 deterministic=true next=M13-01B`.
|
||||
- `python3 -m py_compile tools/web/generate-script-entry-inventory.py`, Node syntax check and
|
||||
`git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `b72667493cfe9957161ef3fb9814180e0cfad5f8aaa1c60c9b6f132e915f3d6f`
|
||||
- checker: `68478f15de4d63ed175e6b580761fd478b1fe9bccbfcaeee82218d13063dfa51`
|
||||
- report: `e024995c53f01beaf725f281f74a6e5ec6018a53435da61a66f5e58a9e50973c`
|
||||
- fixture: `bd6375d02908bfcc57ff7cdeec3f9827bfc4336d1e46e165c5fbbf4d04f19645`
|
||||
- manifest: `d4a305033343ef5fb1ffc073617b59d9012f64b80ecb233e743fb0789a8b4893`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01B`: read script metadata on `.blend` open without executing arbitrary content.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the generator, checker, fixture, report, manifest, and this status entry. Restore M12-07J
|
||||
as the queue tail and move the machine queue back to M13-01A. No parity ledger rollback is required.
|
||||
41
docs/status/M13-01B.md
Normal file
41
docs/status/M13-01B.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-01B Status
|
||||
|
||||
status: done
|
||||
task: read script metadata on `.blend` open without executing arbitrary content
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The real `script_scene.blend` open path reads all three Text sources, verifies source bytes and
|
||||
SHA-256, preserves read-only metadata, and keeps every source `executionStatus=BLOCKED`. A
|
||||
`use_module` autorun request remains `SCRIPT_POLICY_DENIED`; no Python Console, driver, handler,
|
||||
or add-on code executes during open. This task does not add a script execution route.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-script-open-metadata.mjs` ran the production WASM Main reader against the
|
||||
real fixture and passed `script-open-metadata-ok blend=opened textMetadata=read sourceHash=verified execution=DENY autorun=DENY next=M13-01C`.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5495 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/script-open-metadata.spec.ts` passed 1/1.
|
||||
Chromium opened the fixture through `WebEngineClient`, saw three read-only blocked sources and
|
||||
the explicit autorun denial.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed. The checker emits the deterministic
|
||||
report `tests/golden/M13-01B/open-metadata-report.json` bound to the fixture hash.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `66396d5c9a5294021ae077bb162278c74d46de8b52ac8a444a5de4f6d84cfe05`
|
||||
- e2e: `df6412cda113c830996e08c3d66a035dc1ac309e392f5946a762d11121b1926c`
|
||||
- report: `f92470e57c048452134664f7f6208e50b6f087dbcbc33369e6b882c51813990c`
|
||||
- fixture: `2b8fbdb05419e1e61d64777998d6a3b2562f726c17f548cd1852efc723e1a037`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01C`: default-deny autorun, register, install, and driver execution policy codes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, report, manifest, e2e test, and this status entry. Restore M13-01A as the
|
||||
queue tail and move the machine queue back to M13-01B. No parity ledger rollback is required.
|
||||
39
docs/status/M13-01C.md
Normal file
39
docs/status/M13-01C.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# M13-01C Status
|
||||
|
||||
status: done
|
||||
task: default-deny autorun, register, install, and driver execution policy codes
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting manifest parser and execution gate reject autorun/register/install/driver execution
|
||||
requests with stable policy codes. The current bounded contract returns `SCRIPT_POLICY_DENIED` for
|
||||
autorun, `DRIVER_EXECUTION_BLOCKED` for driver expressions, `ADDON_INSTALL_BLOCKED` for add-on
|
||||
install/registration, and `SCRIPT_SANDBOX_UNAVAILABLE` even for a correctly signed script when no
|
||||
isolated sandbox exists. No local eval or script execution is enabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-policy-codes.test.mjs` passed 1/1 and asserts all three denied
|
||||
request codes plus the approved-key sandbox gate.
|
||||
- `node tools/web/check-script-policy-codes.mjs` passed:
|
||||
`script-policy-codes-ok autorun=SCRIPT_POLICY_DENIED driver=DRIVER_EXECUTION_BLOCKED addon=ADDON_INSTALL_BLOCKED sandbox=SCRIPT_SANDBOX_UNAVAILABLE next=M13-01D`.
|
||||
- `npm --prefix web run typecheck`, Node syntax checks and `git diff --check` passed. The report and
|
||||
manifest bind the transpiled production protocol source hashes.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `22588c2198bc8c425ab8e104e8559f0053654ae778aaea3783ec7d54822bc8f4`
|
||||
- unit: `b5a52b8e707963545f1cd71f1a148fa9c9b9d1e4b4c5f51c87d33f8bf3777430`
|
||||
- report: `956db548ee71688a4b89c9a993259d3e57129cd4abe9efd1b9397b3e30b1bf84`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01D`: ensure UI exposes no direct-eval bypass around the scripting policy.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, unit test, report, manifest and this status entry. Restore M13-01B as the queue
|
||||
tail and move the machine queue back to M13-01C. No parity ledger rollback is required.
|
||||
36
docs/status/M13-01D.md
Normal file
36
docs/status/M13-01D.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# M13-01D Status
|
||||
|
||||
status: done
|
||||
task: UI direct-eval bypass gate
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production app, Workers, and protocol TypeScript sources contain no direct `eval(` or
|
||||
`new Function(` bypass. The scan covers 176 non-vendor `.ts/.tsx` files and records the only
|
||||
declared scripting policy entry points: `gateScriptExecution`, `gateServerScriptJob`, and
|
||||
`parseScriptSourceInventory`. Execution remains `DENY`; this static gate does not claim a sandbox.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node tools/web/check-script-ui-bypass.mjs` passed:
|
||||
`script-ui-bypass-ok scanned=176 violations=0 policyEntrypoints=3 report=8e234e128b90036548ab709b86b063de404250da2c5c0a6e25e28969b5cd5c73 next=M13-01E`.
|
||||
- `git diff --check` passed. Vendor-generated Emscripten/Three.js sources are outside the scan;
|
||||
no application or protocol source is allowed to introduce a direct eval constructor.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `f34cb64891c2b22bc3da353f6b864ba3e558d3c286cf716bcb778d9a542cb3d9`
|
||||
- report: `6b050092088508ebd5d769d95a2e66f0cd4020c97f3407724a19b9707f51f6dd`
|
||||
- manifest: `6b28688b3ebcce5629bcfc437d4ca903d0b1e053b32a796690ee4e021726c75b`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01E`: preserve Text data and unknown script sources through save/reopen.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, report, manifest, and this status entry. Restore M13-01C as the queue tail and
|
||||
move the machine queue back to M13-01D. No parity ledger rollback is required.
|
||||
41
docs/status/M13-01E.md
Normal file
41
docs/status/M13-01E.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-01E Status
|
||||
|
||||
status: done
|
||||
task: preserve Text data and unknown script sources through save/reopen
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production WebEngine path opens `script_scene.blend`, saves it, starts a new engine Worker,
|
||||
and reopens the saved bytes. All three Text sources compare exact by metadata and source SHA-256;
|
||||
they remain read-only and `BLOCKED`, including the `use_module` autorun request. No source is
|
||||
rewritten or executed. This does not claim arbitrary script execution or add-on support.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `UPDATE_SCRIPT_SAVE_REOPEN_REPORT=1 CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5498
|
||||
node_modules/.bin/playwright test --config playwright.config.ts --workers=1
|
||||
tests/e2e/script-save-reopen.spec.ts` passed 1/1. A second run without report update on port 5497
|
||||
also passed against the same deterministic report.
|
||||
- `node tools/web/check-script-save-reopen.mjs` passed:
|
||||
`script-save-reopen-ok sources=3 exact=true blocked=true savedBytes=490191 next=M13-01F`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- checker: `7fc9a370cb472636e2699565cb21a1450e3cc8a2c90ffdcdff96533b344afa7c`
|
||||
- e2e: `481f78f3a0cce923b67ab14436cc23cbcd2ce66725de29dc874fea4fb5801227`
|
||||
- report: `0f6869a8ec8342ed87649312d2872ab2c172cbf12d6be81bb0b770ebcbe8a398`
|
||||
- manifest: `889a4e06f7e8c0ea55b3ca4baa9fe85dccbe97053e497a45e3d364ce2b70a7c6`
|
||||
- fixture: `2b8fbdb05419e1e61d64777998d6a3b2562f726c17f548cd1852efc723e1a037`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-01F`: malicious Text, driver, handler, and embedded-module fixtures.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the checker, e2e test, report, manifest, and this status entry. Restore M13-01D as the
|
||||
queue tail and move the machine queue back to M13-01E. No parity ledger rollback is required.
|
||||
44
docs/status/M13-01F.md
Normal file
44
docs/status/M13-01F.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M13-01F Status
|
||||
|
||||
status: done
|
||||
task: malicious Text, driver, handler, and embedded-module fixtures
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Pinned Blender 5.2 generated a malicious fixture containing four source bodies: OS command text,
|
||||
driver import, handler subprocess, and an embedded `register()` module. Chromium opened the file
|
||||
through the production Main reader and kept every source read-only/`BLOCKED`; the embedded module
|
||||
returned `SCRIPT_POLICY_DENIED`. No filesystem marker or execution path is exposed by the test.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `build_blender_5.2.0/bin/blender -b --factory-startup --python
|
||||
tools/web/generate-malicious-script-fixture.py -- tests/files/web/m13_malicious_script_v1
|
||||
tests/golden/M13-01F/malicious-report.json` generated four deterministic source hashes and one
|
||||
`use_module` request.
|
||||
- `node tools/web/check-malicious-script-fixture.mjs` passed:
|
||||
`malicious-script-fixture-ok sources=4 module=1 execution=BLOCKED fixtureSha256=7b1921931afc5bb74a2b73e90b175017c583ea878cdbb66f131718b2d8cd23b5 next=M13-02A`.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5499 node_modules/.bin/playwright test
|
||||
--config playwright.config.ts --workers=1 tests/e2e/malicious-script.spec.ts` passed 1/1.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- generator: `013285befeb59de21a887cefd377adf8cf53ff1c785b28a9c87d29f76f092731`
|
||||
- checker: `36608da893ae59e2e03856a62866ea6e7c349ec4a63200f042b2329e5f61caa9`
|
||||
- e2e: `98fbde6728ddf55cce5262522197a5b4db1dfce618e52259bf0b0c9e0e9165f2`
|
||||
- report: `a628b73411d6f9a761f659ae28867ea9b0c0df30d47668353278b70d4b44180c`
|
||||
- fixture: `7b1921931afc5bb74a2b73e90b175017c583ea878cdbb66f131718b2d8cd23b5`
|
||||
- manifest: `9a0b7c4097b3755365a9fb92b4848e6ac2ddd36ee2c7e9df3cb8808ce247cf3d`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02A`: bounded script manifest limits.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the generator, checker, fixture, report, manifest, e2e test, and this status entry. Restore
|
||||
M13-01E as the queue tail and move the machine queue back to M13-01F. No parity ledger rollback is required.
|
||||
49
docs/status/M13-02A.md
Normal file
49
docs/status/M13-02A.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# M13-02A Status
|
||||
|
||||
status: done
|
||||
task: bounded script manifest limits
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting manifest parser now requires an explicit `sourceByteLength` and
|
||||
`module=false` for every script. It limits script count, aggregate source bytes, dependency count,
|
||||
permission count and per-field execution budgets; canonicalizes entry/dependency paths within the
|
||||
project; and rejects duplicate dependencies, unsafe paths, module execution, unknown permissions
|
||||
and all budget overflow. The parser remains fail-closed and does not execute script content.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-manifest-budgets.test.mjs` passed 4/4 bounded positive and
|
||||
negative cases.
|
||||
- `WEB_TEST_PORT=5513 npm --prefix web run test:script-manifest-budgets` passed unit 4/4 and the
|
||||
production Chromium Worker test 1/1. The browser Worker returned the same canonical paths,
|
||||
aggregate byte count and stable policy/budget errors as the Node protocol test.
|
||||
- `node tools/web/check-script-manifest-budgets.mjs` passed:
|
||||
`script-manifest-budgets-ok accepted=2 totalSourceBytes=256 blocked=6 deterministic=true next=M13-02B`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint`,
|
||||
`npm --prefix web run build`, `npm --prefix web run test:scripting-isolation`, and
|
||||
`git diff --check` passed. The existing isolation gate still reports approved-key
|
||||
`SCRIPT_SANDBOX_UNAVAILABLE` and does not enable execution.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `8d8eae67fa6915f0337850e15247baf01f0abde0b3362fbb120f0b448f1a4cf5`
|
||||
- checker: `b3457324d72ab233cd17a142ea19fac6a0d024dd95de7b8fb5d26810437fb0d2`
|
||||
- unit: `6ce7847a0b745ba4081e4332d012e0b7f86e4906c71c95bdeda8c39977a630ee`
|
||||
- e2e: `1ef4fd4caaeb1fa3d832fc8881823d5284755372575eab186c751f408dc9314c`
|
||||
- report: `860672fe844b7969ca376d4b2708771189d1767efa819f7b97667d8a26438d3a`
|
||||
- manifest: `7148e0387dadffdb55e94e80dc30cfd5cdd40ebe990d06378e90c376d36ebd51`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02B`: canonical serialization fixes the signature input.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M13-02A protocol fields, checker, unit/Chromium tests, worker, report, manifest and this
|
||||
status entry. Restore M13-01F as the queue tail and move the machine queue back to M13-02A. No parity
|
||||
ledger rollback is required.
|
||||
52
docs/status/M13-02B.md
Normal file
52
docs/status/M13-02B.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# M13-02B Status
|
||||
|
||||
status: done
|
||||
task: canonical script manifest serialization
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting protocol now exposes `canonicalizeScriptingManifest` and
|
||||
`serializeScriptingManifest` as the single canonical signature-input path. Script, permission and
|
||||
dependency arrays are sorted with locale-independent code-unit ordering; unknown fields are removed
|
||||
by the parser; canonical JSON has sorted object keys and no whitespace; and security-relevant fields
|
||||
such as source byte length, source hash, permissions, paths, budgets and policy flags remain in the
|
||||
serialized input. Schema changes and source declaration mutations produce a different or rejected
|
||||
input. No signature is accepted and no script is executed by this task.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-manifest-canonical.test.mjs` passed 2/2. It proves order
|
||||
invariance, unknown-field dropping, security-field binding and schema rejection.
|
||||
- `WEB_TEST_PORT=5514 npm --prefix web run test:script-manifest-canonical` passed unit 2/2 and
|
||||
production Chromium Worker 1/1.
|
||||
- `node tools/web/check-script-manifest-canonical.mjs` passed:
|
||||
`script-manifest-canonical-ok equal=true bytes=1923 unknownDropped=true schemaMutation=blocked next=M13-02C`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint`, `npm --prefix web run build`,
|
||||
`node tools/web/check-script-manifest-budgets.mjs`, `node tools/web/check-status-consistency.mjs`
|
||||
and `git diff --check` passed. The M13-02A artifact manifest was refreshed to the current protocol
|
||||
hash after this additive canonical API change, and its checker was rerun successfully; no prior
|
||||
behavior or parity status was changed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `de27fdcd6d16e27a07806ac609f908edfdb7a93d653676174cdd5e06ffa394af`
|
||||
- checker: `5ed344cab6428ae5538a450171ba40c73ff738666515492298e30aaed1394f56`
|
||||
- unit: `33eae0f3ad2ae7243c9ce2835ab8e42186f65f574ab682099766f1d0f4c481f6`
|
||||
- e2e: `5342301165ae82a01b46f5fed0cc0ec34b9813a6ecbc8032900d90b89628e064`
|
||||
- report: `5f4bc0b098ea65de47f1255d30130376d74260e2b912bcd0e28354171fbd07df`
|
||||
- parent manifest: `7148e0387dadffdb55e94e80dc30cfd5cdd40ebe990d06378e90c376d36ebd51`
|
||||
- manifest: `605c656780a206a0d3b81d06b0294108b488a62d2b709e886884a2973c6cb091`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02C`: signer identity, key rotation, revocation and timestamp policy.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the canonical serializer exports, checker, unit/Chromium tests, worker, report, manifest and
|
||||
this status entry; restore M13-02A as the queue tail and move the machine queue back to M13-02B. No
|
||||
parity ledger rollback is required.
|
||||
51
docs/status/M13-02C.md
Normal file
51
docs/status/M13-02C.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# M13-02C Status
|
||||
|
||||
status: done
|
||||
task: signer identity, key rotation, revocation and timestamp policy
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting protocol now has a versioned trust-policy schema for signer identity and key
|
||||
lifecycles. It validates ED25519 public-key identity, publisher ownership, active/revoked status,
|
||||
not-before/not-after windows, revocation timestamps, same-publisher rotation predecessors and
|
||||
acyclic rotation chains. `maxClockSkewMs` binds policy timestamps to an explicit bounded window.
|
||||
`resolveScriptSigner` only returns `ELIGIBLE` with `cryptographicVerification=REQUIRED`; revoked,
|
||||
expired, not-yet-valid, missing and publisher-confused keys remain structured `BLOCKED` results.
|
||||
This task does not verify signatures or enable script execution.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-trust-policy.test.mjs` passed 3/3. It covers valid active
|
||||
rotation, revoked predecessor, invalid/cross-publisher/cyclic rotation, revocation metadata,
|
||||
public-key format and timestamp failures.
|
||||
- `WEB_TEST_PORT=5516 npm --prefix web run test:script-trust-policy` passed unit 3/3 and production
|
||||
Chromium Worker 1/1.
|
||||
- `node tools/web/check-script-trust-policy.mjs` passed:
|
||||
`script-trust-policy-ok active=key:new revoked=REVOKED crossPublisher=SCRIPT_POLICY_DENIED policyExpired=POLICY_EXPIRED crypto=REQUIRED next=M13-02D`.
|
||||
- `npm --prefix web run typecheck` passed; M13-02A and M13-02B checkers were rerun after the
|
||||
additive protocol change and passed. No parity ledger or execution route changed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `c6e206b29e7cacc3e23e2ac12a3d523a9c0b16ff29759126dab13c8665547421`
|
||||
- checker: `0e55ce20d142f2bcbc5ce9c6fb955ef2771d284dff636c79da3f59a33b8b0aeb`
|
||||
- unit: `59ac77bcc1086e0a0e914cb77d647db5d34c7160202e7aad52948b7277769551`
|
||||
- e2e: `614091bda15367090bc78a6f465fb10d02d0aa08775b5088699b12e2490034d2`
|
||||
- report: `0f59f733920edbbe5cb799e5f50ff31d19e55ced98e7a890828f6337a237e4bd`
|
||||
- unit: `aac3ff0a1c7ae27e35112614bedabc02bb248882ec9b0b52d65f9794d06830d8`
|
||||
- parent manifest: `605c656780a206a0d3b81d06b0294108b488a62d2b709e886884a2973c6cb091`
|
||||
- manifest: `89745daca88371335f4bd56982791266461082066c6c1345056fbc697bb7e6a2`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02D`: signature only approves declared content and source hash changes invalidate it.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the trust-policy schema, parser/resolver, checker, unit/Chromium tests, worker, report,
|
||||
manifest and this status entry; restore M13-02B as the queue tail and move the machine queue back to
|
||||
M13-02C. No parity ledger rollback is required.
|
||||
46
docs/status/M13-02D.md
Normal file
46
docs/status/M13-02D.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# M13-02D Status
|
||||
|
||||
status: done
|
||||
task: signature verification binds declared content
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
`verifyScriptManifestSignature` now verifies the canonical per-script manifest input with the
|
||||
trusted ED25519 key. The input includes the declared source SHA-256 and all policy-relevant fields,
|
||||
while excluding only the signature field itself. A source hash or signature mutation therefore
|
||||
returns `SCRIPT_SIGNATURE_INVALID`; revoked or otherwise ineligible keys return
|
||||
`SCRIPT_POLICY_DENIED`. Verification remains a policy gate and does not enable script execution.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test --test-name-pattern=M13-02D web/tests/unit/script-trust-policy.test.mjs` passed the
|
||||
M13-02D case (1 passed, 3 unrelated cases skipped).
|
||||
- `WEB_TEST_PORT=5520 npm --prefix web run test:script-signature` passed the focused Node case and
|
||||
production Chromium Worker E2E (1/1).
|
||||
- `node tools/web/check-script-signature.mjs` passed:
|
||||
`script-signature-ok verified=SCRIPT_SIGNATURE_VERIFIED sourceHashChanged=SCRIPT_SIGNATURE_INVALID revoked=SCRIPT_POLICY_DENIED next=M13-02E`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint`, `npm --prefix web run build` and
|
||||
`git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `f4e8ff45d06efcfa9e634ef28e654241d70554ed05dfe9c3fecd9f6eef166ce0`
|
||||
- checker: `2d6e7b403dd6d401eb1a41978016b40bd1fb86120464e09f185de4445c177fa4`
|
||||
- unit: `aac3ff0a1c7ae27e35112614bedabc02bb248882ec9b0b52d65f9794d06830d8`
|
||||
- e2e: `8a882fc8fa2c0c4e2eab3660810cec0f60d2f7475f62a1bb406fc3b2bdf60882`
|
||||
- report: `957daf8e5899714cc5ce253b1f0fb2b258f1cc966238fff31e2626f8f56feb3a`
|
||||
- manifest: `c6b79a77e4b7ffe5f4a9ba785a30305f9cf6e86caf89b38a4b303a86ab662a31`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02E`: permission default-minimization and unknown-permission blocking.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M13-02D checker, report, manifest, status entry and focused package command; restore
|
||||
M13-02C as the queue tail and move the machine queue back to `M13-02D`. No parity ledger rollback
|
||||
is required.
|
||||
42
docs/status/M13-02E.md
Normal file
42
docs/status/M13-02E.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M13-02E Status
|
||||
|
||||
status: done
|
||||
task: permission default-minimization and unknown-permission blocking
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
`resolveScriptPermissions` now grants an empty set by default and only grants an explicitly
|
||||
requested permission when it is already declared by the script manifest. Unknown, duplicate or
|
||||
undeclared requests return `SCRIPT_POLICY_DENIED`; manifest declarations still reject unknown
|
||||
permissions during parsing. This task adds no execution capability.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-permission-policy.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5521 npm --prefix web run test:script-permission-policy` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-permission-policy.mjs` passed:
|
||||
`script-permission-policy-ok defaultGranted=0 declared=READ_MAIN escalation=SCRIPT_POLICY_DENIED unknown=SCRIPT_POLICY_DENIED next=M13-02F`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `5df074e676542475009a4980fecaf3fdde009d149de84b9ca146647fb6aa1c02`
|
||||
- checker: `169ab096295e08c5a630ef09d814da6ce742efd7a7143ff9a17984b4ca20593a`
|
||||
- unit: `43bb6796616f3f92d71b51ef2a119a4e263864121a03356764e4b9c9241c4043`
|
||||
- e2e: `dc13412a44f277bbe68315da0d38a2c4aa520d7489c81e7c908f9768c0547b7e`
|
||||
- report: `8dc41e75620ba5bcb08d0edc52c3994e4f4dbc37ad3633757634bf10fe97b252`
|
||||
- manifest: `691376d3cd33d3cd339b7195034abaf89cc02fba7e740c40ff051c4496400eef`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-02F`: replay, key-confusion, expiry and multi-signature negative cases.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove `resolveScriptPermissions`, the focused worker/unit/E2E/checker, report, manifest, status
|
||||
entry and package command; restore M13-02D as the queue tail and move `nextTask` back to `M13-02E`.
|
||||
42
docs/status/M13-02F.md
Normal file
42
docs/status/M13-02F.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M13-02F Status
|
||||
|
||||
status: done
|
||||
task: signature replay, key-confusion and expiry negative cases
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The signature gate now has an independent negative-case matrix covering missing keys, expired and
|
||||
not-yet-valid keys, publisher/key confusion, and a signature copied to a different script. Every
|
||||
case remains fail-closed with `SCRIPT_POLICY_DENIED` or `SCRIPT_SIGNATURE_INVALID`; no execution
|
||||
route is added. Canonical script ordering remains accepted when the script's own signature matches.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-signature-negative.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5522 npm --prefix web run test:script-signature-negative` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-signature-negative.mjs` passed:
|
||||
`script-signature-negative-ok missing=SCRIPT_POLICY_DENIED expired=SCRIPT_POLICY_DENIED notYetValid=SCRIPT_POLICY_DENIED swapped=SCRIPT_SIGNATURE_INVALID next=M13-03A`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `49b289110a6533fcd1a29ad78be00792fd3c0d251c6027bae0440f5daba929a1`
|
||||
- checker: `35f2e6727aef5e6ea2e2623e2effa6ea0356faaf66d417976db7f5bbe671a38c`
|
||||
- unit: `8b9c8d63c97fce07299622b9ad261791a97bb91a6ed340e72c24c55e685978bd`
|
||||
- e2e: `26c52ef67d6b1ea2994d92637826994e98e5234e042049f8d69a905f5cdb3309`
|
||||
- report: `d23a2ae5613b2442ad79420aa344ebfe3767d10ac19b3ea30a62afcccd3a167c`
|
||||
- manifest: `283673b21e6c9b89dc6ecb7007f3cecf28d53a84ec84f3f8b52373c055538a74`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03A`: sandbox capability scope with no DOM, host-worker, OPFS, IndexedDB or network access.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the M13-02F negative-case worker, tests, checker, report, manifest, status entry and package
|
||||
command; restore M13-02E as the queue tail and move `nextTask` back to `M13-02F`.
|
||||
42
docs/status/M13-03A.md
Normal file
42
docs/status/M13-03A.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# M13-03A Status
|
||||
|
||||
status: done
|
||||
task: sandbox capability scope
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting protocol now defines a versioned all-deny sandbox scope. DOM, host-worker,
|
||||
OPFS, IndexedDB and network capabilities must each be explicitly `false`; any enabled, missing or
|
||||
unknown scope version is rejected with a stable policy/protocol error. This is a capability contract
|
||||
only: script execution remains disabled and no sandbox implementation is claimed.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-scope.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5523 npm --prefix web run test:script-sandbox-scope` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-scope.mjs` passed:
|
||||
`script-sandbox-scope-ok dom=SCRIPT_POLICY_DENIED hostWorker=SCRIPT_POLICY_DENIED opfs=SCRIPT_POLICY_DENIED indexedDB=SCRIPT_POLICY_DENIED network=SCRIPT_POLICY_DENIED execution=DISABLED next=M13-03B`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `27058fbb602791cbe6691fa14b3bc9c3d6cdea79641ba9c72fe18b6226d2a651`
|
||||
- checker: `ad26ea3b078e480ba8f99cbf8dbd0d9b135c7605f4a3958d24845b7f5f8b0f43`
|
||||
- unit: `a15da2e645d2d681c7e9ac1380f6b224d196d1d2e78d20f1bacad01e138753d4`
|
||||
- e2e: `49930747e6663f79b61093706318b72e59388d79e3e1cc105bc1571693326667`
|
||||
- report: `ba5784c751d5a347f38aa522ffcbed270d38fb474f0f10a2d06ea501d0234021`
|
||||
- manifest: `76a7ce0fd3a38fb770c9cedccbd05ed566b931caa1782fdae898d3b66c3a20bf`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03B`: fixed CPU, wall-time, memory, message and output-byte budgets.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the sandbox scope parser, focused worker/tests/checker, report, manifest, status entry and
|
||||
package command; restore M13-02F as the queue tail and move `nextTask` back to `M13-03A`.
|
||||
41
docs/status/M13-03B.md
Normal file
41
docs/status/M13-03B.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-03B Status
|
||||
|
||||
status: done
|
||||
task: sandbox CPU, wall, memory, message and output budgets
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The scripting protocol now parses bounded CPU, wall-time, memory, message and output-byte budgets.
|
||||
Each field has a fixed maximum and all overflow or schema drift returns `SCRIPT_BUDGET_EXCEEDED` or
|
||||
`PROTOCOL_MISMATCH`. The budget is a contract only; execution remains disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-budget.test.mjs` passed 2/2.
|
||||
- `WEB_TEST_PORT=5524 npm --prefix web run test:script-sandbox-budget` passed unit 2/2 and
|
||||
production Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-budget.mjs` passed:
|
||||
`script-sandbox-budget-ok cpu=SCRIPT_BUDGET_EXCEEDED wall=SCRIPT_BUDGET_EXCEEDED memory=SCRIPT_BUDGET_EXCEEDED message=SCRIPT_BUDGET_EXCEEDED output=SCRIPT_BUDGET_EXCEEDED execution=DISABLED next=M13-03C`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `ed836a032b33f54154fdd36f9f6e99ee43ca1755ea0dd8326474a13300ec965e`
|
||||
- checker: `ab10d1d32c20022c848be4b33e1be846168a9ca4cf22ac932ea000001e9e2391`
|
||||
- unit: `caa40fc58a73aa4d433285c94009e5436a29fbcb6b4e18b74b27c49fd0b07490`
|
||||
- e2e: `8be77fd55e76149bfe2e0e449d81a62707ebfa430514936808ec4805fc96e07c`
|
||||
- report: `4355710e07e95cbb0f96a82fdefca3607f363d3aea9ba89c332e8a4708b7bed2`
|
||||
- manifest: `b61978c22cdfffe81b812e2eea788d52326f9f0ebb4540e77f86dc9e19ff21dd`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03C`: host calls use explicit allowlist and structured parameters.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the sandbox budget parser, focused worker/tests/checker, report, manifest, status entry and
|
||||
package command; restore M13-03A as the queue tail and move `nextTask` back to `M13-03B`.
|
||||
43
docs/status/M13-03C.md
Normal file
43
docs/status/M13-03C.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M13-03C Status
|
||||
|
||||
status: done
|
||||
task: explicit host-call allowlist and structured parameters
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting protocol now accepts only five host-call names: `READ_MAIN`, `READ_ASSET`,
|
||||
`WRITE_MAIN`, `WRITE_ASSET` and `SUBMIT_SERVER_JOB`. Each request has a version, request/script IDs,
|
||||
permission binding and call-specific structured parameters. Unknown calls, permission confusion,
|
||||
unknown fields, unsafe paths and malformed payloads fail closed. Parsed calls remain
|
||||
`execution=DISABLED`; no host operation is invoked.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-host-call.test.mjs` passed 3/3.
|
||||
- `WEB_TEST_PORT=5525 npm --prefix web run test:script-host-call` passed unit 3/3 and production
|
||||
Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-host-call.mjs` passed:
|
||||
`script-host-call-ok accepted=5 blocked=4 structured=true execution=DISABLED next=M13-03D`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `b26a37f20e829172bb70fbe9b9e3a194923818127cccbe8bbc55f6d994be55e8`
|
||||
- checker: `e90042f4eefd9e89da6d1cead87ca1cb9db9b3bd65ba8028593e093903577e2e`
|
||||
- unit: `e7679cd902c75504204d528343e4fa6be316d1c56c02b2871a67637aa847a1ec`
|
||||
- e2e: `7b17a7da440aee07895101efb8e1eb13bfbebbe54e955bde09299f6b33d6aaf9`
|
||||
- report: `afb140a3aecff1de52c4363e7cd0ce476b0c9140ffdc016ec13a085049f6dd1a`
|
||||
- manifest: `54318c45b11dd1707fecf78b0637257158102ea1dbb88d4d442e33b77df2cdbf`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03D`: sandbox crash/timeout terminates the job without changing Main revision.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the host-call parser, focused worker/tests/checker, report, manifest, status entry and package
|
||||
command; restore M13-03B as the queue tail and move `nextTask` back to `M13-03C`.
|
||||
46
docs/status/M13-03D.md
Normal file
46
docs/status/M13-03D.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# M13-03D Status
|
||||
|
||||
status: done
|
||||
task: sandbox crash/timeout isolation
|
||||
updated: 2026-08-18 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The sandbox job termination receipt now converts crash, wall-time timeout and cancellation into
|
||||
stable fail-closed statuses. Every terminated receipt keeps `mainRevisionAfter` equal to
|
||||
`mainRevisionBefore`, publishes no result, releases temporary bytes, and remains
|
||||
`execution=DISABLED`; a result received after termination is rejected with
|
||||
`SCRIPT_SANDBOX_LATE_RESULT`.
|
||||
|
||||
The Chromium test starts a production Worker that throws for the crash case and a production Worker
|
||||
that would publish a delayed result for the timeout case. The host observes the crash, terminates the
|
||||
timeout Worker before its delayed message, and confirms no late message arrives.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-isolation.test.mjs` passed 3/3.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5532 npm --prefix web run test:script-sandbox-isolation` passed unit 3/3 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-isolation.mjs` passed:
|
||||
`script-sandbox-isolation-ok crash=SCRIPT_SANDBOX_CRASHED timeout=SCRIPT_SANDBOX_TIMEOUT revisionUnchanged=true late=SCRIPT_SANDBOX_LATE_RESULT next=M13-03E`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `8c810ee7c8bd15d83ecfb4981068f947536bfe8c9e63b906861f42b8465722da`
|
||||
- checker: `e5c0c3c7cd500c269ae43a1a9eb05589e82aad28199ab4f11ad1167b486f6937`
|
||||
- unit: `47986f93638fdc18b817b03222484f4691dc294185040eaebac8e1f386bc1549`
|
||||
- e2e: `2c16c42f09827a0c0100ef2cc6295ca6bc96933ed7475e08b1fa195d7940c141`
|
||||
- report: `4af91cdb21101039b379136c7559b46df55f4f5ab5478c05c1c57cd6e1624d2a`
|
||||
- manifest: `8066013f3d356ba438c36d1f1ea1cf692dbb4f60b086f552072e36b783a96d42`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03E`: cancellation after termination must not publish a late message or cache.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the isolation Worker additions, focused tests/checker, report, manifest and this status entry;
|
||||
restore M13-03C as the queue tail and move `nextTask` back to `M13-03D`.
|
||||
45
docs/status/M13-03E.md
Normal file
45
docs/status/M13-03E.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M13-03E Status
|
||||
|
||||
status: done
|
||||
task: sandbox cancellation result gate
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Cancellation now has an explicit terminated-job receipt. The receipt preserves the Main revision,
|
||||
publishes no result, releases temporary bytes and remains `execution=DISABLED`. The production
|
||||
Chromium Worker schedules a late message containing a cache key; the host cancels and terminates it
|
||||
before publication, then observes a bounded late window with zero messages and zero cache writes.
|
||||
Late results supplied after cancellation are rejected with `SCRIPT_SANDBOX_LATE_RESULT`.
|
||||
|
||||
This task does not claim Worker/port/timer disposal or same-session recovery; those remain M13-03F/G.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-cancellation.test.mjs` passed 2/2.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5533 npm --prefix web run test:script-sandbox-cancellation` passed unit 2/2 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-cancellation.mjs` passed:
|
||||
`script-sandbox-cancellation-ok status=CANCELLED late=SCRIPT_SANDBOX_LATE_RESULT lateMessages=0 cacheWrites=0 next=M13-03F`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `6699fc0a19e0736823f164e707a420655803e36019cf0071f7ff9c760d25e9f2`
|
||||
- worker: `0feb70c8c491cc24ebfe6c3e267b92522d616b6f260efcecfa57cf489d0742c0`
|
||||
- checker: `b6fbe7102b7d0808673931c66797f8976e79b21bd4c32e429f21832c6090708e`
|
||||
- unit: `374cc87f66bd42226b750e387663ef8c86bef92348fa7cbc6ed7f0027945204d`
|
||||
- e2e: `b233d9cafa1f70798ec19d76ca936abb610681522264a12237f532eb98e09fca`
|
||||
- package: `6499a70fc4a93c925053ddf5009c74d9c10754b443afc9d58e898fe20d7f1b05`
|
||||
- report: `066d9f19716b8229f2cf7755ec3009a3edef942ebab5f70159bec7f2afbaf71f`
|
||||
- manifest: `0cdf625e6bd3ed7aca43318a3b04353cb806c51cfa4cf3c5dae9a65a0eae2e69`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03F`: dispose Worker, MessagePort, timers, abort controllers and buffers to zero.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the cancellation Worker, focused tests/checker, report, manifest, package command and this
|
||||
status entry; restore M13-03D as the queue tail and move `nextTask` back to `M13-03E`.
|
||||
44
docs/status/M13-03F.md
Normal file
44
docs/status/M13-03F.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M13-03F Status
|
||||
|
||||
status: done
|
||||
task: sandbox resource disposal gate
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The sandbox Worker now owns an explicit disposal receipt. Both `MessagePort` endpoints, the timer,
|
||||
`AbortController`, transferable buffer, pending request and cache reference are observed before
|
||||
disposal and are all zero after the first dispose. A second dispose is accepted and reports
|
||||
`idempotent=true`; the cleared timer produces no late message. Script execution remains
|
||||
`DISABLED`, and this task does not claim same-session recovery or server isolation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-dispose.test.mjs` passed 2/2.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5534 npm --prefix web run test:script-sandbox-dispose` passed unit 2/2 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-dispose.mjs` passed:
|
||||
`script-sandbox-dispose-ok ports=0 timers=0 abortControllers=0 buffers=0 pending=0 cacheReferences=0 idempotent=true next=M13-03G`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `f3d9f667c3809cfad0f52bc6028d93e36e25c4b639fb6081c9c933fbad0ebc0a`
|
||||
- worker: `2a074b05d301c4083e60534eb9452aabf5d95aea0ab316fa657441ef4bcd5c96`
|
||||
- checker: `6549bd10f588281d23c4bea705fd164252c9e3f44d8f4b93c893a2c410907135`
|
||||
- unit: `6e00aa6286aae0eabc1345c04c7628dcc9acb32d51c1c27436a0e1b4c170b64c`
|
||||
- e2e: `b240d92c90e0d81272cd9cb3c0eb4e7d77102ce2e49ad05c761f763d1812b18e`
|
||||
- package: `0f06cd7ccdeed4213b6cb956aecf94e60dceff811ad8c3a2e239397685cfc1bf`
|
||||
- report: `2dbd3e79939b500c0fc83216c51f258b88ead42a667ed1a6da755e893d7f73c6`
|
||||
- manifest: `96abc7c7613ef4c18c64b84ffb8420c39369f9e4733bd1fa4d7d9ee9e53d6f89`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-03G`: recover a small script in the same session with a new Worker generation while keeping
|
||||
the Main revision/source hash stable and extending the audit hash chain.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the dispose protocol, Worker, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-03E as the queue tail and move `nextTask` back to `M13-03F`.
|
||||
43
docs/status/M13-03G.md
Normal file
43
docs/status/M13-03G.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M13-03G Status
|
||||
|
||||
status: done
|
||||
task: same-session sandbox recovery and audit continuity
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
A denied script request can be resumed in the same session after a Worker generation change from 4
|
||||
to 5. The Main revision remains 11, and the source and canonical manifest hashes remain stable.
|
||||
Two default-deny audit entries use distinct request IDs, sequence 1/2, and a continuous
|
||||
`previousEntrySha256 -> entrySha256` chain. Replay and source-hash tampering are rejected. This task
|
||||
does not enable Python execution or claim Blender server isolation.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/script-sandbox-recovery.test.mjs` passed 2/2.
|
||||
- `CHROME_PATH=/usr/bin/google-chrome-stable WEB_TEST_PORT=5535 npm --prefix web run test:script-sandbox-recovery` passed unit 2/2 and Chromium Worker E2E 1/1.
|
||||
- `node tools/web/check-script-sandbox-recovery.mjs` passed:
|
||||
`script-sandbox-recovery-ok generation=4->5 revision=11 sourceStable=true manifestStable=true sequence=1,2 chain=true replay=SCRIPT_MANIFEST_INVALID tamper=SCRIPT_MANIFEST_INVALID next=M13-04A`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `8034faded657d49e1376ea42051bc302a090b485024a9ff3781e46aa82638b64`
|
||||
- worker: `7b02331c375d4fb7dbadadd179f0ab9a0e336c8b95fabb071c06e67f3e7b3fe4`
|
||||
- checker: `612015a3fca44bae0f0b78e622f044a5297ed8aa3a0efc774a40f0d47ddbdc9e`
|
||||
- unit: `69a2d34e38d591043ff62b2d305bd9aae684ecebd9ecba718580d77318931226`
|
||||
- e2e: `73176e513f115ba917be74f62a5deb8fe2918fafa8a84c9294e80d2a86b8f1ed`
|
||||
- package: `3df02b6049ac5d7185c23aef7764933ee460fedeb6595b3861272b0d49da5ecd`
|
||||
- report: `9057b3f49c3bb15cf53d638ada4bd2743949d3914173cd3799414489d584111d`
|
||||
- manifest: `5cd365eeebbd6a7f56f380af103b66f2beb11eb49cb6db6adb49972b572cf2ec`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04A`: create an unpredictable one-shot directory for each real Blender server job.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the recovery protocol, Worker, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-03F as the queue tail and move `nextTask` back to `M13-03G`.
|
||||
44
docs/status/M13-04A.md
Normal file
44
docs/status/M13-04A.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# M13-04A Status
|
||||
|
||||
status: done
|
||||
task: server job one-shot directory
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The server-side job allocator creates an unpredictable `0700` directory below a configured absolute
|
||||
root for each request. Directory names do not contain the request ID, two concurrent jobs receive
|
||||
distinct directories, and successful or failed cleanup removes the directory exactly once. Repeated
|
||||
cleanup is idempotent. This task does not claim read-only source mounts, process limits or Blender
|
||||
execution.
|
||||
|
||||
Browser E2E is not applicable: this is a Node server filesystem boundary. The checker uses real
|
||||
temporary directories and `fs.stat`/`fs.rm` calls.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/server-job-isolation.test.mjs` passed 2/2.
|
||||
- `npm --prefix web run test:server-job-directory` passed unit 2/2 and the independent checker.
|
||||
- `node tools/web/check-server-job-isolation.mjs` passed:
|
||||
`server-job-directory-ok allocated=2 cleaned=2 unique=1 requestIdsHidden=1 mode=0700 residual=0 idempotent=1 next=M13-04B`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `3aa5678a2c2769e4db5bb8f5c755b97e23045c4106e5636459748ab9b41929cd`
|
||||
- checker: `b8d0e741144f742946246370bd35820d806686fb00dc0b040c925cf16f2179da`
|
||||
- unit: `b1ac3324332180f7b3522f135520e7b5dace334dc461c92f2bce48fbcba2e147`
|
||||
- package: `0c2633da831e7ca10cf74797650353b6dfb1507ed5957688d34bc97f9a6dd193`
|
||||
- report: `07ed66fe0b2e1f1bbdba1cfb1089b052a5961d38f761bfcf79d8362980d2d502`
|
||||
- manifest: `fd2407a7b9fefe67e2d77ed844e6c2ca17cdc4a746857a5825a38ff02ab664e3`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04B`: source read-only mount and independent writable output directory.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the directory allocator, focused tests/checker, report, manifest, package command and this
|
||||
status entry; restore M13-03G as the queue tail and move `nextTask` back to `M13-04A`.
|
||||
41
docs/status/M13-04B.md
Normal file
41
docs/status/M13-04B.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# M13-04B Status
|
||||
|
||||
status: done
|
||||
task: server source read-only and output isolation
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Each allocated server job now gets a `source/` directory and a separate `output/` directory. The
|
||||
source directory is `0555` and the staged `.blend` is `0444`; a source overwrite fails with
|
||||
`EACCES`. The output directory is `0700` and accepts result bytes. Cleanup temporarily restores
|
||||
the source directory permission so the one-shot job directory can be removed without residue.
|
||||
This task does not claim OS/container CPU, memory or process limits.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/server-job-isolation.test.mjs` passed 3/3.
|
||||
- `npm --prefix web run test:server-job-workspace` passed unit 3/3 and the independent checker.
|
||||
- `node tools/web/check-server-job-workspace.mjs` passed:
|
||||
`server-job-workspace-ok sourceDir=0555 sourceFile=0444 sourceWrite=EACCES outputDir=0700 outputWrite=OK distinct=1 residual=0 next=M13-04C`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `3aa5678a2c2769e4db5bb8f5c755b97e23045c4106e5636459748ab9b41929cd`
|
||||
- checker: `9490c2eeb9980073fc1fe77fdba1fb6e4ef528de8eb666d9eaf1fb582ba658c2`
|
||||
- unit: `b1ac3324332180f7b3522f135520e7b5dace334dc461c92f2bce48fbcba2e147`
|
||||
- package: `3df02b6049ac5d7185c23aef7764933ee460fedeb6595b3861272b0d49da5ecd`
|
||||
- report: `650a643cc92617d068cb96d8bd4303429ef169ea89e3d4cb63e3ce5e2428e6d2`
|
||||
- manifest: `9bc906b9e4c9751229f03271ef45a5925122b89b15bfe775591775f121ce1a4c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04C`: enforce CPU, memory, process, file, wall-time and output budgets at the server boundary.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the workspace protocol additions, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-04A as the queue tail and move `nextTask` back to `M13-04B`.
|
||||
43
docs/status/M13-04C.md
Normal file
43
docs/status/M13-04C.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# M13-04C Status
|
||||
|
||||
status: done
|
||||
task: server job resource budget gate
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Server jobs now have fixed CPU, memory, process, file, wall-time and output-byte limits. Budget
|
||||
parsing rejects undeclared fields and out-of-range values. A usage receipt is marked
|
||||
`enforced=true` only when every measured value is within its corresponding limit; each of the six
|
||||
over-limit cases returns `SERVER_JOB_BUDGET_EXCEEDED` and remains `execution=DISABLED`.
|
||||
|
||||
This is the resource contract and usage gate. OS/container enforcement is proven by the later real
|
||||
process task and is not claimed here.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `node --test web/tests/unit/server-job-resource-budget.test.mjs` passed 2/2.
|
||||
- `npm --prefix web run test:server-job-resource-budget` passed unit 2/2 and the independent checker.
|
||||
- `node tools/web/check-server-job-resource-budget.mjs` passed:
|
||||
`server-job-budget-ok cpu=bounded memory=bounded process=bounded files=bounded wall=bounded output=bounded overages=6 execution=DISABLED next=M13-04D`.
|
||||
- `npm --prefix web run typecheck`, `npm --prefix web run lint` and `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- protocol: `9746f0aef9dd76411320792dee1213c03755a3c03a87bbc4cbf88d4324c728d6`
|
||||
- checker: `5599f4e25fc3ceca18e04be322450a4dc5bb6ce9c72c3abe9f1afc9c81851ff8`
|
||||
- unit: `05212b2aa639f4c37e37e1cac0597d9b367a1280e519240f073762394914dc63`
|
||||
- package: `3df02b6049ac5d7185c23aef7764933ee460fedeb6595b3861272b0d49da5ecd`
|
||||
- report: `76ba684966bf7e680b0ebfc630ae9e080f04dd6daa6dd744bbb22dcff43f8eb1`
|
||||
- manifest: `d00fff709b57909ec418ff0e476dca97281fc39456f674c63b51248377fc6ab2`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04D`: default-deny network policy with explicit declared-origin admission.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the resource budget protocol, focused tests/checker, report, manifest, package command and
|
||||
this status entry; restore M13-04B as the queue tail and move `nextTask` back to `M13-04C`.
|
||||
24
docs/status/M13-04D.md
Normal file
24
docs/status/M13-04D.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# M13-04D Status
|
||||
|
||||
status: done
|
||||
task: server job network policy
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
Server jobs default to `DENY`. Only an explicitly declared canonical HTTPS or loopback origin is
|
||||
`ALLOWED`; missing, undeclared, credential-bearing, path-bearing, public HTTP and invalid origins
|
||||
return `SERVER_NETWORK_DENIED` or `SERVER_NETWORK_POLICY_INVALID`. Execution remains `DISABLED`.
|
||||
|
||||
Evidence: `node --test web/tests/unit/server-job-network-policy.test.mjs` 2/2;
|
||||
`npm --prefix web run test:server-job-network-policy` passed; checker output
|
||||
`server-job-network-ok default=DENY declaredOrigin=ALLOWED missing=SERVER_NETWORK_DENIED undeclared=SERVER_NETWORK_DENIED execution=DISABLED next=M13-04E`;
|
||||
typecheck, lint and `git diff --check` passed.
|
||||
|
||||
Artifact hashes: protocol `0dc3698383fbfa511bebfeca41504c7c04a8302d47168cfae94f01f2a11a316c`,
|
||||
checker `6f3e9cd9f988313863345f392036e6dbb522102c969197034800f419e497ad92`, unit
|
||||
`c0ba10ccd2fb6ec8878a1b4a54bc6a12e49d35818566e0d55ef307779e8c8b77`, report
|
||||
`37bcba2666e8c76c2e07d23e285737004affbb0372ec6dd84bb6802dba551527`, manifest
|
||||
`11ce246597e3321b346ed4fed00edba22708d97250163d332d7ba8a003d8849a`.
|
||||
|
||||
Next task: `M13-04E`, fixed Blender background/factory-startup runtime identity.
|
||||
22
docs/status/M13-04E.md
Normal file
22
docs/status/M13-04E.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# M13-04E Status
|
||||
|
||||
status: done
|
||||
task: pinned Blender server startup
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
Pinned Blender 5.2.0 LTS now passes a real server preflight using only `--background`,
|
||||
`--factory-startup`, the fixed `tools/web/server-job-startup.py`, and a fixed business argument.
|
||||
The structured receipt confirms background mode, runtime version and argv. Execution remains
|
||||
`DISABLED`; this task does not claim result publication.
|
||||
|
||||
Evidence: `node tools/web/check-server-job-startup.mjs` output
|
||||
`server-job-startup-ok blender=5.2 background=1 factory=1 userPrefs=0 fixedScript=1 execution=DISABLED next=M13-04F`;
|
||||
typecheck, lint and `git diff --check` passed. Artifact hashes: startup
|
||||
`c8c5b5a7a7880d4df9477a94a98e54e328baf582ade649807067f988484e1f12`, checker
|
||||
`66b2e25efe0e7455348e8f488cd0f6ebef07f916fcf6541680e7d18e4f69ab10`, report
|
||||
`c67d2972e584782d03479dbdb36dae0976074978f4ce9a48e41e7ad5aea66089`, manifest
|
||||
`a24ea87bcf305bc15d8ae70b2abd03aa16ffbd6b127d5e9da9da23617d7201cc`.
|
||||
|
||||
Next task: `M13-04F`, bounded and redacted stdout/stderr.
|
||||
40
docs/status/M13-04F.md
Normal file
40
docs/status/M13-04F.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# M13-04F Status
|
||||
|
||||
status: done
|
||||
task: bounded and redacted server stdout/stderr
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Server job output is normalized through a production receipt before publication. Credentials, bearer/basic
|
||||
tokens, secret headers and Unix/Windows/file URL paths are replaced; UTF-8 output is truncated at fixed
|
||||
stdout/stderr byte budgets with an explicit marker. The receipt records original/emitted bytes, redaction
|
||||
count and truncation state. Server execution remains `DISABLED`; process cancellation and result publication
|
||||
are separate tasks.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-output-redaction` passed 3/3 unit tests and the independent checker.
|
||||
- Checker output: `server-job-output-ok stdoutTruncated=1 stderrTruncated=1 redactions=6 totalBounded=1 execution=DISABLED next=M13-04G`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `a24ea87bcf305bc15d8ae70b2abd03aa16ffbd6b127d5e9da9da23617d7201cc`
|
||||
- protocol: `5a58e7080324b399905c6a20a313225153ba94c75a55d21c4bbdd957ae4a2462`
|
||||
- checker: `5c2db9d3313484bb68ac65822828467b3f99cb03e8374935757cfcb4b4ed908d`
|
||||
- unit: `4ae6266bce22f84e73113b93a590a0c32d9452e748003af251a602024d0c6db5`
|
||||
- package: `52781eb2650133b43271889a22ce38023e611641da15411d31698c6cfc0ce19c`
|
||||
- report: `cb6e3ed8d6cc0a69b333b6bff3199593bdfbae14fa7fa700dcb12e9e9cea519a`
|
||||
- manifest: `b5b4b26183dc48ebcae009e49999010d9b60d512f5daa4674a0aff0577d6602c`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04G`: cancel Blender process tree and clean the one-shot directory.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the output receipt protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04E` as the queue tail.
|
||||
38
docs/status/M13-04G.md
Normal file
38
docs/status/M13-04G.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04G Status
|
||||
|
||||
status: done
|
||||
task: server process-tree cancellation
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Real server jobs now run in a detached process group on POSIX and are cancelled as a tree. The cancellation
|
||||
path sends SIGTERM to the group, escalates to SIGKILL after the grace window, waits for the group to exit,
|
||||
and performs one idempotent job-directory cleanup. Windows uses `taskkill /T /F`. The receipt reports the
|
||||
actual signal path, cleanup count and orphan count. Execution remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-cancellation` passed 2/2 real-process unit tests and the checker.
|
||||
- Checker output: `server-job-cancel-ok state=CANCELLED tree=SIGTERM_GROUP cleanup=1 orphan=0 residual=0 execution=DISABLED next=M13-04H`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `b5b4b26183dc48ebcae009e49999010d9b60d512f5daa4674a0aff0577d6602c`
|
||||
- protocol: `74fbbac806f34904bc9cb8e40eaf386cb60d44d978973950f1809262d311ec95`
|
||||
- checker: `751ecafc642595d0de69b618e223cbff49d414f2958fc371371e4a668d66a8cc`
|
||||
- unit: `39ac445ff51a9bfe249363204cf2edca906b16bf67ab1f8321166b440eba8629`
|
||||
- package: `ca092a9a1d48ac41dc20f978bb26c8268adde9f7602a06459c7df8c2cb2d4cc7`
|
||||
- report: `61f5c3ad315f94bac48e58627fcc46015c173dd9f303d5914acb8dbbe93caa97`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04H`: map timeout/OOM/non-zero exit/signal to stable error codes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the process control protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04F` as the queue tail.
|
||||
38
docs/status/M13-04H.md
Normal file
38
docs/status/M13-04H.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04H Status
|
||||
|
||||
status: done
|
||||
task: stable server process fault codes
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Timeout, bounded-memory OOM, signal termination and non-zero exit are converted to stable server error
|
||||
codes. Classification precedence is cancellation, timeout, OOM, signal, then non-zero exit. Failed receipts
|
||||
keep the base/current revision equal, set `publish=false`, and expose no internal process details. Execution
|
||||
remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-fault-codes` passed 3/3 unit tests and the checker.
|
||||
- Checker output: `server-job-faults-ok timeout=SERVER_JOB_TIMEOUT oom=SERVER_JOB_OOM signal=SERVER_JOB_SIGNAL exit=SERVER_JOB_EXIT_FAILED revisionPreserved=1 publish=0 execution=DISABLED next=M13-04I`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `7103a25ec7eb4a1c7f0d9f7acfb5ed30da32c87d512d6f9d53e081db275f7b89`
|
||||
- protocol: `858360b4468a7b6cf796fc83a1627ba18626b61a0799f83531de996ea374519b`
|
||||
- checker: `cb67246ef3df111525ca5e14af0546154ea2beee930b9840ad4ac7e2ebbb91ec`
|
||||
- unit: `3551e28d78e5069c3d97eabcacac824bf142f54fdcb3ad4904668909af1cc545`
|
||||
- package: `77bae66fd3885e36d2ead6f261754724144e5f51fafc5ccad9863dfc8e5ab548`
|
||||
- report: `01999232f926496909fc9ef072e19aadb688822d3f9d7e03b42871ac5d54a0f6`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04I`: verify source/settings/build/output hashes before OPFS commit.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the fault classifier, unit/checker, report, manifest, package command and this status entry; restore
|
||||
`M13-04G` as the queue tail.
|
||||
38
docs/status/M13-04I.md
Normal file
38
docs/status/M13-04I.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04I Status
|
||||
|
||||
status: done
|
||||
task: server result hash binding and atomic OPFS handoff
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Server output publication requires request identity plus source, settings and Blender build SHA-256 values
|
||||
to match the expected request. Output bytes are staged, read back, atomically renamed to the request result
|
||||
path, and read back again before a committed receipt is returned. Tampered output, identity drift, partial
|
||||
stage and quota failures remain unpublished. Execution remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-result-binding` passed 2/2 unit tests and the checker.
|
||||
- Checker output: `server-job-result-ok source=bound settings=bound build=bound output=verified tamper=blocked quota=blocked atomic=1 execution=DISABLED next=M13-04J`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `ba530ddff6e6fdd84057444ce757fad05a30d825a5915abebe2d5910a689af7f`
|
||||
- protocol: `ecf3bddef53e2766dcc055ec027b04c14e3d884132c7fdea476663617364ad86`
|
||||
- checker: `b0fbffd2937ab20e72d337bb5ff63ccf188ccf8a939d8ccc8b4878d80c9a4a19`
|
||||
- unit: `c5538798aa6263b8a1c20270a019f8b4fb8b176b141a6411b72aad21a457bfd0`
|
||||
- package: `5d269d4e5ff4385d919c0ee33f996dcb814e3e415da25dbf3b4dbdc3312fbe24`
|
||||
- report: `ec63faeba35a641a22c3b3a69757bd37e8e9acaa1dda11a64faf7bed80439784`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-04J`: idempotent request retry and conflicting-result isolation.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the result-binding protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04H` as the queue tail.
|
||||
38
docs/status/M13-04J.md
Normal file
38
docs/status/M13-04J.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# M13-04J Status
|
||||
|
||||
status: done
|
||||
task: server request idempotency and conflict isolation
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
`projectId/requestId` is now an idempotency key. An exact retry verifies and reuses the existing result;
|
||||
different output or source/settings/build identity returns a stable conflict and cannot overwrite the bound
|
||||
result. Different requests use separate result and receipt files. Concurrent duplicate requests share one
|
||||
in-flight submission and resolve as one commit plus one reuse. Execution remains `DISABLED`.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:server-job-idempotency` passed 3/3 unit tests and the checker.
|
||||
- Checker output: `server-job-idempotency-ok first=COMMITTED retry=REUSED conflict=BLOCKED isolated=1 concurrent=REUSED execution=DISABLED next=M13-05A`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `f9658954d3dbd0cd1edd696c10f6a1b880bb3288c91a39a47ca84c4496046a97`
|
||||
- protocol: `15eca7550964c9985e26a22a7900d3f3aa69fdef35fe5962b48a8f55ebba5863`
|
||||
- checker: `02247ffda07c095373642a7fa22268bb9f5ac181d41571f7fff685812976d3c4`
|
||||
- unit: `6ee08e67cd8493e856f67309bd6562316eca42ef52dd4a9aad3a15efdc4b6b41`
|
||||
- package: `5b47e94cf828fc9d3021019eed9922eb67815aba5416266d8c967c7cb5bd96ba`
|
||||
- report: `31f95a8cc1c4792303986b8b5987ab02fc11a77ab25fd76b31c02d1ed1b104d1`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05A`: CSP denies inline script, eval, data script and undeclared origins.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the idempotency protocol, unit/checker, report, manifest, package command and this status entry;
|
||||
restore `M13-04I` as the queue tail.
|
||||
45
docs/status/M13-05A.md
Normal file
45
docs/status/M13-05A.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# M13-05A Status
|
||||
|
||||
status: done
|
||||
task: CSP default-deny policy
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The deployment contract now requires one CSP on every response: same-origin default/script/worker/connect
|
||||
sources, no inline or eval execution, no data/blob script source, and object/base/frame embedding denied.
|
||||
The Vite source, entry HTML, production source tree and built JS/HTML are scanned for dynamic code and data
|
||||
scripts. The deployment HTTP checker verifies the policy on normal, missing and entry responses. Resource-
|
||||
specific Worker/WASM/font/image/media rules remain in M13-05B.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:csp-policy` passed.
|
||||
- `node tools/web/check-deployment-contract.mjs` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed; built output was scanned by the CSP checker.
|
||||
- Checker output: `csp-policy-ok inline=DENY eval=DENY dataScript=DENY undeclaredConnect=DENY responses=3 execution=DISABLED next=M13-05B`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `d230ae49dbf38cd9e95e7379a1a49332e478d3d23b3638730d2ec6167204c368`
|
||||
- contract: `3f2b0b10c5a5698be2adda61af80cfb9cb9291fb9797994bfa66a77b7b511eeb`
|
||||
- deployment server: `a5734ce9760f65cf5bade8cc209454d39fa963ad7dfaf20653728a9d7a57b04c`
|
||||
- contract checker: `5e2d80f5c1377420f4779291fa73c206741ed415e751e79ce5edae7ba039febf`
|
||||
- CSP checker: `f97ab074da860e3f8489e520c8bb5932f858409136ef25cca56247bb1310340d`
|
||||
- index: `16b7691b191127f84c5143e23aecdfc203dc9e279d34cb270b37631fcbd5f856`
|
||||
- Vite: `fd160c685ed780738e2b37ce9a32e5d4718e11a2875e12d86ddad310213abaf3`
|
||||
- package: `5b47e94cf828fc9d3021019eed9922eb67815aba5416266d8c967c7cb5bd96ba`
|
||||
- report: `9c7c64bb021161a1165a7c089ccf3f4897877635914260f6f0b0da119a5036fb`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05B`: verify resource-specific CSP for Worker, WASM, font, image and media paths.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the CSP contract/checker changes, report, manifest, package command and this status entry; restore
|
||||
`M13-04J` as the queue tail.
|
||||
31
docs/status/M13-05B.md
Normal file
31
docs/status/M13-05B.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# M13-05B Status
|
||||
|
||||
status: done
|
||||
task: resource-specific CSP policy
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The deployment contract now separates same-origin policy for Worker, WASM, font, image and media
|
||||
resources. Chromium loaded same-origin Worker, WASM, image and media resources, and rejected data-image,
|
||||
blob-Worker and cross-origin connect attempts. WASM uses only the explicit `wasm-unsafe-eval` source
|
||||
expression; JavaScript `eval` remains denied. Resource responses and 404 responses carry the same policy.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:csp-resource-policy` passed the HTTP resource matrix and Chromium browser gate.
|
||||
- `node tools/web/check-deployment-contract.mjs` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05C`: production/build/test dependency inventories.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the resource-specific CSP/MIME changes, checker, report, manifest, package command and this status;
|
||||
restore `M13-05A` as the queue tail.
|
||||
27
docs/status/M13-05C.md
Normal file
27
docs/status/M13-05C.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# M13-05C Status
|
||||
|
||||
status: done
|
||||
task: production/build/test dependency inventories
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Evidence
|
||||
|
||||
`web/package.json` and `web/package-lock.json` are parsed as the only dependency sources. Deterministic
|
||||
transitive closures contain production=3, build=135 and test=6 packages; every package is classified and
|
||||
records its path, version, resolved URL and lockfile integrity. A fresh regeneration is byte-identical.
|
||||
|
||||
- `npm --prefix web run test:dependency-inventory` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05D`: severity gates and documented dependency exceptions.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the inventory generator/checker, report, manifest, package command and this status; restore
|
||||
`M13-05B` as the queue tail.
|
||||
18
docs/status/M13-05D.md
Normal file
18
docs/status/M13-05D.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# M13-05D Status
|
||||
|
||||
status: done
|
||||
task: dependency severity gates and exceptions
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
The severity policy is machine-readable: BLOCKER/HIGH block, MEDIUM requires review and LOW is tracked.
|
||||
Exceptions require a non-empty owner, non-expired ISO date, reason and alternative control. Production
|
||||
inventory has zero findings and zero exceptions, while four negative/positive exception cases are checked.
|
||||
|
||||
- `npm --prefix web run test:dependency-severity-policy` passed.
|
||||
- `npm --prefix web run typecheck` passed.
|
||||
- `npm --prefix web run build` passed.
|
||||
- `git diff --check` passed.
|
||||
|
||||
Next task: `M13-05E`, SBOM/license/source-offer binding.
|
||||
13
docs/status/M13-05E.md
Normal file
13
docs/status/M13-05E.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# M13-05E Status
|
||||
|
||||
status: done
|
||||
task: SBOM/license/source-offer and archive binding
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
The supply-chain checker binds SPDX 2.3 to the lockfile and notices hashes, verifies the corresponding
|
||||
source offer and source archive contents, checks top-level archive SHA256SUMS, and records the current
|
||||
commit. Binary/source archive validators also pass independently; script execution remains disabled.
|
||||
|
||||
Next task: `M13-05F`, malicious input matrix.
|
||||
14
docs/status/M13-05F.md
Normal file
14
docs/status/M13-05F.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# M13-05F Status
|
||||
|
||||
status: done
|
||||
task: malicious input matrix
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
The production blend loader rejected five malformed blend cases. Existing production protocol tests
|
||||
rejected malformed image previews, fonts, media cache manifests, shader node graphs, script manifests and
|
||||
GLB inputs; archive metadata rejected six ZIP/TAR traversal, link, duplicate and bomb cases without
|
||||
extraction. All matrix categories are stable reject paths and execution remains disabled.
|
||||
|
||||
Next task: `M13-05G`, fuzz crash minimization and regression capture.
|
||||
37
docs/status/M13-05G.md
Normal file
37
docs/status/M13-05G.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# M13-05G Status
|
||||
|
||||
status: done
|
||||
task: fuzz crash minimization and regression capture
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The deterministic runner replays 16 mutations in each of the blend, image, font, node-graph and script
|
||||
manifest domains using seed `1511506142`. Every case returns one structured `ACCEPTED` or `REJECTED`
|
||||
receipt; a non-zero runner exit first writes a replayable corpus sample. This run completed 80 cases with
|
||||
zero crashes and an empty minimized corpus. Script execution remains disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:fuzz-regression` passed.
|
||||
- Checker output: `fuzz-regression-ok seed=1511506142 cases=80 crashes=0 corpus=0 execution=DISABLED next=M13-05H`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Artifact Hashes
|
||||
|
||||
- parent manifest: `34043df0515f4b422a2b265d38978dd3c7f21acd12753c99f9a50f9b23f8bd60`
|
||||
- runner: `a4d5d1b743b454705b1c3a257f1f36d1fea8abd77442e11fb1fec9e2905a3f79`
|
||||
- checker: `55c8fa3776b22eb3f2e2ffd1629f0092384df30ef3913699a1ba93b283d641d8`
|
||||
- package: `1feb509789d7f06019390bd86197bb9851cd520fd9fe310d1e29bfc3d2ef3f18`
|
||||
- report: `5eb4a5469732697be7910fded3ce34cf2898735f767d94c1abbe0dd264bcc0d9`
|
||||
|
||||
## Next Task
|
||||
|
||||
`M13-05H`: fuzz corpus replay and release-boundary exclusion.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the fuzz runner/checker, report, manifest, package command and this status entry; restore
|
||||
`M13-05F` as the queue tail.
|
||||
30
docs/status/M13-05H.md
Normal file
30
docs/status/M13-05H.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# M13-05H Status
|
||||
|
||||
status: done
|
||||
task: script audit record integrity
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production scripting audit protocol now has an independent integrity gate. Two default-deny audit
|
||||
records are validated with strictly increasing ISO timestamps, contiguous sequence numbers, unique request
|
||||
IDs, canonical entry digests and a continuous previous-entry hash chain. Replay, time reversal, sequence
|
||||
mutation, entry digest mutation and chain mutation all return `SCRIPT_MANIFEST_INVALID`; execution remains
|
||||
disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:script-audit-integrity` passed 2 unit tests and the checker.
|
||||
- Checker output: `script-audit-integrity-ok entries=2 sequence=1,2 requestIds=unique time=ordered chain=true replay=SCRIPT_MANIFEST_INVALID tamper=3 execution=DISABLED next=M14-01A`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01A`: freeze the current Chromium release, engine and archive hashes.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the audit integrity checker/unit, report, manifest, package command and this status entry; restore
|
||||
`M13-05G` as the queue tail.
|
||||
32
docs/status/M14-01A.md
Normal file
32
docs/status/M14-01A.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# M14-01A Status
|
||||
|
||||
status: done
|
||||
task: Chromium, engine and archive identity freeze
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The Chromium baseline is frozen at `150.0.7871.128`. The checker resolves and hashes the actual browser
|
||||
executable, validates every single/pthread engine resource against `engine-manifest.json`, and validates
|
||||
both release archives against the regenerated `RC_MANIFEST.json` and `SHA256SUMS.txt`. Execution remains
|
||||
disabled.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run release:offline` passed deterministic binary/source rebuild twice.
|
||||
- `node tools/web/create-rc-manifest.mjs && node tools/web/check-rc-manifest.mjs` passed.
|
||||
- `npm --prefix web run test:chromium-freeze` passed with browser `150.0.7871.128`, two engine variants,
|
||||
and two archive bindings.
|
||||
- `npm --prefix web run typecheck` passed; execution remains `DISABLED`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01B`: Firefox capability probe using the frozen field set.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the Chromium freeze checker, report, manifest, package command and this status entry; restore
|
||||
`M13-05H` as the queue tail.
|
||||
21
docs/status/M14-01B.md
Normal file
21
docs/status/M14-01B.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# M14-01B Status
|
||||
|
||||
status: done
|
||||
task: Firefox capability probe
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
Firefox `153.0` was probed against the rebuilt production assets with COOP/COEP isolation. WASM, Worker,
|
||||
OPFS, IndexedDB, WebGL2, OffscreenCanvas and cross-origin isolation passed. WebGPU is explicitly
|
||||
`BLOCKED/WEBGPU_UNAVAILABLE`; it does not change the Chromium-only release claim.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:firefox-capability` passed.
|
||||
- Checker output: `firefox-capability-ok version=153.0 wasm=PASS,worker=PASS,opfs=PASS,indexedDB=PASS,webgl2=PASS,webgpu=BLOCKED,offscreen=PASS,isolation=PASS execution=DISABLED next=M14-01C`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01C`: WebKit capability probe with the same fields.
|
||||
21
docs/status/M14-01C.md
Normal file
21
docs/status/M14-01C.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# M14-01C Status
|
||||
|
||||
status: done
|
||||
task: WebKit capability probe
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
WebKit `26.5` was probed against the rebuilt production assets with COOP/COEP isolation. WASM, Worker,
|
||||
IndexedDB, WebGL2, OffscreenCanvas and isolation passed. OPFS and WebGPU are explicitly blocked; the
|
||||
result does not change the Chromium-only release claim.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:webkit-capability` passed.
|
||||
- Checker output: `webkit-capability-ok version=26.5 wasm=PASS,worker=PASS,opfs=BLOCKED,indexedDB=PASS,webgl2=PASS,webgpu=BLOCKED,offscreen=PASS,isolation=PASS execution=DISABLED next=M14-01D`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01D`: probe identity and GPU/OS adapter recording.
|
||||
33
docs/status/M14-01D.md
Normal file
33
docs/status/M14-01D.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# M14-01D Status
|
||||
|
||||
status: done
|
||||
task: probe identity and GPU/OS adapter recording
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The production Chromium probe records observed browser identity, OS kernel/runtime identity,
|
||||
hardware concurrency, WebGL2 vendor/renderer/version, WebGPU adapter identity, and cross-origin
|
||||
isolation. WebGPU is recorded as `BLOCKED/WEBGPU_ADAPTER_UNAVAILABLE` in this headless environment;
|
||||
the result does not claim WebGPU support. The report is bound to the exact worker/WASM asset hashes
|
||||
used by the probe and carries a canonical identity SHA-256.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:probe-identity` passed twice (one report-generation run and one frozen
|
||||
report verification run).
|
||||
- Checker output: `probe-identity-ok version=151.0.7922.34 os=linux/x64 webgl2=PASS,webgpu=BLOCKED identity=3c6f898e1b6ffd39862505b8e7dde8fd29369204e1670a013859f74ccaf1c1eb execution=DISABLED next=M14-01E`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-01E`: Chromium WebGPU fail-closed boundary. Firefox and WebKit are excluded by the project
|
||||
Chromium-only iron rule.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the probe checker, report, manifest, package command and this status/task entry; keep
|
||||
`M14-01C` as the queue tail.
|
||||
29
docs/status/M14-01E.md
Normal file
29
docs/status/M14-01E.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# M14-01E Status
|
||||
|
||||
status: done
|
||||
task: Chromium WebGPU fail-closed boundary
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Chromium routing was checked against the production render protocol. A bounded Eevee request using
|
||||
WebGPU returns `BLOCKED/WEBGPU_RENDERER_UNAVAILABLE` when no bundled adapter is available, while the
|
||||
same bounded request using WebGL2 remains `READY/WEB_LOCAL_BOUNDED`. This task does not launch Firefox
|
||||
or WebKit.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:chromium-webgpu-boundary` passed.
|
||||
- Checker output: `chromium-webgpu-boundary-ok webgpu=BLOCKED/WEBGPU_RENDERER_UNAVAILABLE webgl2=READY execution=DISABLED next=M14-04A`.
|
||||
- `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04A`: Chromium GPU/memory budget device tier selection.
|
||||
|
||||
## Rollback
|
||||
|
||||
Remove the Chromium boundary checker, report, manifest, package command and this status/task entry;
|
||||
restore `M14-01D` as the queue tail.
|
||||
25
docs/status/M14-04A.md
Normal file
25
docs/status/M14-04A.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# M14-04A Status
|
||||
|
||||
status: done
|
||||
task: Chromium GPU/memory budget device tier selection
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Added a bounded device-budget selector driven only by the real Chromium M14-01D identity report.
|
||||
The observed SwiftShader renderer and unavailable WebGPU adapter select `CONSERVATIVE`; untrusted,
|
||||
missing, or fallback adapters cannot expand budgets. Fixed `CONSERVATIVE`, `BALANCED`, and `HIGH`
|
||||
limits are explicit and unknown tiers fail closed. Firefox/WebKit are excluded by the iron rule.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run test:chromium-device-budget` passed: 3 unit tests plus the production identity
|
||||
report checker.
|
||||
- Checker output: `chromium-device-budget-ok tier=CONSERVATIVE reason=UNTRUSTED_ADAPTER identity=3c6f898e1b6ffd39862505b8e7dde8fd29369204e1670a013859f74ccaf1c1eb execution=DISABLED next=M14-04B`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04B`: Chromium DPR 1/1.5/2/3 canvas and raycast consistency.
|
||||
26
docs/status/M14-04B.md
Normal file
26
docs/status/M14-04B.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04B Status
|
||||
|
||||
status: done
|
||||
task: Chromium DPR 1/1.5/2/3 canvas and raycast consistency
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Shared viewport DPR and CSS-bounds NDC helpers now drive the main-thread and Offscreen viewport
|
||||
boundaries. Chromium production verification ran at device scale factors 1, 1.5, 2 and 3; the
|
||||
declared renderer cap of 2 was applied, backing dimensions matched the browser canvas, CSS dimensions
|
||||
remained `679x321`, and the same center raycast selected the same object at every scale.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-dpr-consistency` passed: 2 protocol tests and 4 real Chromium
|
||||
production contexts.
|
||||
- Checker output: `chromium-dpr-ok dpr=1,1.5,2,3 css=679x321 selection=stable execution=DISABLED next=M14-04C`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04C`: Chromium mouse/touch/pen pointer identity and cancellation contract.
|
||||
26
docs/status/M14-04C.md
Normal file
26
docs/status/M14-04C.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04C Status
|
||||
|
||||
status: done
|
||||
task: Chromium mouse/touch/pen pointer identity and cancellation contract
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
The main-thread and Offscreen viewport paths now record a shared pointer observation for mouse,
|
||||
touch, and pen input. Pointer identity, pressure, tilt, button/buttons and `pointercancel` are
|
||||
preserved with bounded values; unknown pointer types and invalid IDs fail closed. Chromium production
|
||||
events verified down/cancel pairs for all three pointer types. Firefox/WebKit are excluded.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-pointer-contract` passed: 2 protocol tests and real Chromium
|
||||
mouse/touch/pen down/cancel events.
|
||||
- Checker output: `chromium-pointer-ok types=mouse,touch,pen cancel=PASS execution=DISABLED next=M14-04D`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04D`: Chromium IME composition guard for incomplete operators.
|
||||
26
docs/status/M14-04D.md
Normal file
26
docs/status/M14-04D.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04D Status
|
||||
|
||||
status: done
|
||||
task: Chromium IME composition guard for incomplete operators
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Added an explicit IME composition state machine and connected it to the App global shortcut gate.
|
||||
Composition start/update records pending text and blocks operator shortcuts; composition end clears
|
||||
the block without dispatching an incomplete operator. A real Chromium page dispatched composition
|
||||
events and `G`; UI revision remained unchanged during composition. Firefox/WebKit are excluded.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-ime-guard` passed: 2 protocol tests and real Chromium
|
||||
compositionstart/update/keydown/compositionend events.
|
||||
- Checker output: `chromium-ime-ok composing=BLOCKED_OPERATOR shortcut=G revision=0 execution=DISABLED next=M14-04E`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04E`: Chromium US/non-US/dead-key/modifier keymap fixture.
|
||||
26
docs/status/M14-04E.md
Normal file
26
docs/status/M14-04E.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# M14-04E Status
|
||||
|
||||
status: done
|
||||
task: Chromium US/non-US/dead-key/modifier keymap fixture
|
||||
updated: 2026-08-19 America/New_York
|
||||
enablingTask: false
|
||||
parityStateChange: false
|
||||
|
||||
## Scope
|
||||
|
||||
Added a versioned keyboard observation contract preserving layout character (`key`), physical key
|
||||
(`code`), location, repeat, composition state, dead-key identity and modifier flags. Chromium
|
||||
production events verified US, non-US character, dead-key and modifier fixtures. Firefox/WebKit are
|
||||
excluded.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `npm --prefix web run build` passed.
|
||||
- `npm --prefix web run test:chromium-keymap-fixture` passed: 2 protocol tests and 4 real Chromium
|
||||
keyboard fixtures.
|
||||
- Checker output: `chromium-keymap-ok fixtures=US,NON_US,DEAD_KEY,MODIFIER observations=4 execution=DISABLED next=M14-04F`.
|
||||
- `npm --prefix web run typecheck` and `git diff --check` passed.
|
||||
|
||||
## Next Task
|
||||
|
||||
`M14-04F`: Chromium touch modal cancel, two-finger navigation and single pen Main commit.
|
||||
@@ -1,7 +1,8 @@
|
||||
# N-023 Asset、Library 与 IO
|
||||
|
||||
状态:`BLOCKED`(asset catalog、来源/许可证元数据、真实 Main library inventory、库依赖与
|
||||
IO 安全门已落地;Append/Link/Override Main、非 GLB 本地导入和跨桌面重导入未实现)
|
||||
IO 安全门已落地;bounded Append Main 及其 canonical persistence 已完成,Link/Override Main、
|
||||
非 GLB 本地导入和跨桌面重导入仍未实现)
|
||||
|
||||
## 完整对标盘点基线
|
||||
|
||||
@@ -91,8 +92,35 @@ M12-03D 已把同一 source-hash-bound closure 送入 WASM Worker 的 authoritat
|
||||
link/append context 递归导入 Object、Mesh、Material 和 packed Image,Main commit 前核对 source
|
||||
locator、root、closure 与 base revision;四个 ID 均无 `ID.lib`/override、映射为可写 `LOCAL_MAIN`,
|
||||
并只产生一个新的 SceneIR revision。stale revision 与 local ID collision 在 Main mutation 前阻断,
|
||||
失败路径回滚完整 history state。该项只证明单 transaction Main append,undo/redo/save/reopen 与
|
||||
desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
失败路径回滚完整 history state。
|
||||
|
||||
M12-03E 已在同一 Chromium/WASM Main 路径完成联合持久化门:append 只推进一个 revision,undo
|
||||
移除 Object/Mesh/Material/Image 四个 closure ID,redo 恢复同一 canonical graph;save/reopen 后
|
||||
再次读取的依赖边、geometry、UV、material slot 和 packed image Float32 pixel hash 与 M12-03C
|
||||
desktop report 精确一致。图像比较只对 Blender bottom-up `Image.pixels` 与 Canvas top-down row
|
||||
做规范化;当前 SceneIR 缺省的 `Image.colorSpace` 使用 desktop sRGB semantic default,若字段出现
|
||||
则必须匹配,不放宽其它字段。该证据仍不覆盖 Link/Override 或完整 N-023 IO parity。
|
||||
|
||||
M12-03F 已用独立 Blender 5.2 desktop fixture 冻结 LINK 语义。只链接一个 Object root,Mesh、
|
||||
Material 和 packed Image 依赖随 source library 保留;四个 ID 的 `library` 均为
|
||||
`m12_link_source.blend`、`isLibraryOverride=false`,并映射为 `SOURCE_LIBRARY/readOnly=true`。
|
||||
target 保存并重开后 stable mapping、依赖边、geometry/UV/material slot 和 packed image Float32
|
||||
pixel hash 不变。该 enabling evidence 仍不开放 linked writer 或声明完整 Link parity。
|
||||
|
||||
M12-03G 已为 linked Object/Mesh/Material/Image writer 建立统一 fail-closed gate。object transform、
|
||||
mesh geometry/material slot、material property/image node 和 packed image data 六类操作在
|
||||
`SOURCE_LIBRARY/readOnly=true` context 下全部返回 `LINKED_DATA_MUTATION_BLOCKED`,且
|
||||
`recoverable=false`;stale revision 先返回 `REVISION_CONFLICT`,未知字段、operation 和 owner
|
||||
substitution 也在 Main 前阻断。M12-03H 又将 reload 限定为匹配 source library generation/revision 的
|
||||
单一 linked snapshot 替换;stale、跳代、重复 identity 和 source substitution 均不发布新状态。该项仍不
|
||||
实现 relocate、override 或 LINK Main transaction;M12-03I 的 missing-library placeholder 仍是有界
|
||||
reference-preservation 证据,不是完整资源恢复。
|
||||
|
||||
M12-04A-J 又冻结 declared source-origin admission、canonical project path、path/origin safety、
|
||||
symlink/hardlink resolution、metadata-first read、entry/total/path/range/conflict budget 与 cancellation
|
||||
rollback。取消、quota 和 OOM 的部分 staging 都会清零并保持 committed revision/SHA-256 不变,
|
||||
同一 storage instance 可继续提交小 archive;6 个恶意 ZIP/TAR fixture 又进入确定性长期回归。
|
||||
该组有界证据仍不实现完整 archive decoder、fuzz 或 N-023 全域 parity。
|
||||
|
||||
## 已验证切片
|
||||
|
||||
@@ -101,8 +129,30 @@ desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
缺许可证和哈希不匹配会拒绝。
|
||||
2. N-023-A/B(部分):catalog 与 library dependency 图做确定性拓扑检查并返回 load order;
|
||||
content-addressed index 报告 `LOCAL_BOUNDED`,OPFS 只在运行时 API 存在时报告 `PROBE_REQUIRED`。
|
||||
3. N-023-C(门):现有 GLB 导出与 USD semantic analysis 可放行;GLTF/OBJ/PLY/STL、
|
||||
USD/Alembic 实际导入保持 `IO_FORMAT_UNSUPPORTED`,库 mutation 需要真实 Main。
|
||||
3. N-023-C(门):现有 GLB 导出与 USD semantic analysis 可放行;M12-05A 已从 pinned Blender
|
||||
5.2 runtime 生成 GLTF/GLB/OBJ/STL/PLY/USD/Alembic operator/build inventory,但没有把清单
|
||||
当作执行 receipt;M12-05B 仅放行已有 bounded GLB local export,其余 import/export local/server
|
||||
route 均保持 `BLOCKED`;M12-05C 又让 UI registry 只消费 matrix 声明且 runtime 可执行的 route,
|
||||
文件选择器仅接受 `.blend`,operator search 隐藏 blocked/undeclared 组合;M12-05D 再用
|
||||
pinned Blender 5.2 runtime receipt 在执行前确认 operator registered/build option/RNA identity,
|
||||
M12-05E 又要求 source/settings/runtime 三重 hash 与 parent inventory identity,且不从扩展名推断能力;
|
||||
M12-06A 已由同一 pinned runtime 生成五个独立 Mesh/PBR/UV/skin/animation GLB fixture,并用
|
||||
semantic report 与逐字节二次生成固定输入基线;M12-06B 又由生产 Web parser 在 Node 与
|
||||
Chromium Worker 对 topology/attributes/materials/nodes/animations 做 exact canonical 比较;
|
||||
M12-06C-G 又完成 Main persistence、loss report、desktop re-import、negative budget 和双向取消/
|
||||
Worker restart/真实 OPFS quota 恢复;M12-07A 又冻结 pinned Blender OBJ 单 Mesh position/
|
||||
normal/UV/material-group 输入;M12-07B 又冻结 OBJ 双对象/负索引/相对纹理来源/坏 face 负例;
|
||||
M12-07C 已完成 bounded Web-to-desktop OBJ round-trip 与 texture-origin loss report,但
|
||||
UV/skin mismatch、GLB import UI route 和 OBJ Web route 仍保持阻断;M12-07D 已冻结 Blender
|
||||
STL binary/ASCII 两个独立 runtime variant;M12-07E 又对标 normal/unit/degenerate/trailing,
|
||||
trailing 保持 stricter Web block;M12-07F 又完成 STL Web-to-desktop round-trip/material loss
|
||||
report,STL Web route 仍保持阻断;M12-07G 又冻结 PLY ASCII 与 binary little-endian 两个
|
||||
独立 desktop capability variant;M12-07H 又完成 bounded PLY vertex/face/color/custom property
|
||||
mapping 与 `PLY_UNKNOWN_PROPERTY` loss report;M12-07I 又让 big-endian、坏 list、超大 count
|
||||
在 Worker 中稳定 fail-closed;M12-07J 又完成 OBJ/STL/PLY cancellation/OOM/restart/small recovery,
|
||||
但 PLY Web route 仍保持阻断;
|
||||
GLTF/OBJ/PLY/STL、USD/Alembic 实际导入仍保持 `IO_FORMAT_UNSUPPORTED`,
|
||||
库 mutation 需要真实 Main。
|
||||
4. N-023-A/B(部分):预览字节先验 SHA-256 和 byte length,再校验 PNG signature/尺寸;
|
||||
WebP 仅在 RIFF/WEBP 容器签名正确时进入后续解码门,不从元数据伪造预览内容。
|
||||
5. N-023-E:项目路径、外部 URI、archive entry 数量/单项/总量、压缩展开比率均有边界。
|
||||
@@ -110,9 +160,11 @@ desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
packed/external 状态、只读标志和 archive-parent dependency;1024 library/每库 1024 dependency、
|
||||
重复 ID、缺依赖、依赖环与项目外路径由 SceneIR 再校验。缺外部库字节时返回
|
||||
`LINKED_LIBRARY_RESOURCE_REQUIRED`,不从路径伪造 SHA-256 或声称已加载。
|
||||
7. N-023-E(archive 结构门):除 traversal 与展开比预算外,重复规范路径、文件/目录前缀冲突、
|
||||
累计压缩/解压字节和声明源长度不一致均拒绝;`planIOArchiveRanges` 按路径生成确定性、安全整数
|
||||
compressed offset 计划。它为后续流式解包提供边界,不代表已有 ZIP decoder。
|
||||
7. N-023-E(archive 结构门):symlink/hardlink 在写前解析到临时根;ZIP central directory/TAR
|
||||
manifest 必须先读;entry/total/path、展开比、重叠 range、重复路径与文件/目录前缀冲突均拒绝。
|
||||
取消会删除真实 staging、保持 committed identity 且发布数为零;quota/OOM 部分写入也会清零,
|
||||
并允许同一 storage instance 恢复小 archive。三类 ZIP 与三类 TAR 恶意二进制 fixture 确定性
|
||||
重建、验证真实容器 metadata 后全部 fail-closed;这些门不代表已有 ZIP/TAR decoder。
|
||||
8. N-023-E(NanoVDB range 基础件):`.nvdb` manifest 要求连续、32-byte 对齐、逐块 hash;
|
||||
HTTP source 只接受与 manifest 精确一致的 `206 Content-Range`,并按块校验后消费;临时错误重试、
|
||||
稳定 ETag/If-Range、response-body 偏移续传、错位/短响应拒绝均已完成。OPFS 原子
|
||||
@@ -125,11 +177,16 @@ desktop canonical report 的联合一致性仍由 M12-03E 验证。
|
||||
|
||||
## 仍然阻断
|
||||
|
||||
- N-023-B:Append undo/redo/save/reopen、Link/Library Override、reload/relocate 和完整真实 Main
|
||||
parity;M12-03D 的单 transaction append 已有独立证据,但不解除本项阻断。
|
||||
- N-023-B:linked relocate、missing-library recovery、Library Override 和完整真实 Main parity;
|
||||
M12-03D/E 已证明 bounded Append 的单 transaction 与 desktop canonical persistence,M12-03F/G/H/I
|
||||
已冻结 desktop LINK source-library/read-only contract、linked writer fail-closed 与
|
||||
matching-generation reload、missing-reference preservation 和 desktop override ownership/property
|
||||
fixture、单一 verified override writer、freshness gate、negative cases、三 lane command matrix 与
|
||||
declared source-origin admission、canonical project-path normalization 与 path/origin security gate,
|
||||
但不解除本项阻断。
|
||||
- N-023-C/D:GLTF/OBJ/PLY/STL、USD/Alembic import/export/save/reopen/desktop reimport。
|
||||
- N-023-E:真实 zip decoder/fuzz、OPFS quota/recovery、license/source offer 发布审计和大文件
|
||||
流式性能;archive 路径冲突、双向字节预算与确定性 range plan 已完成。
|
||||
- N-023-E:真实 ZIP/TAR decoder/fuzz、license/source offer 发布审计和大文件流式性能仍阻断;
|
||||
archive link/metadata/budget/conflict/cancellation/quota/OOM 与恶意 fixture regression 已完成。
|
||||
- N-023-E(VDB):GPU page resident LRU 已完成;64 MiB–1 GiB bundle 中断/内存性能门仍阻断。
|
||||
|
||||
## 验收
|
||||
@@ -154,6 +211,13 @@ npm --prefix web run test:asset-preview-display
|
||||
npm --prefix web run test:library-operation-inventory
|
||||
npm --prefix web run test:library-operation-identity
|
||||
npm --prefix web run test:library-main-append
|
||||
npm --prefix web run test:library-link-safety
|
||||
npm --prefix web run test:library-metadata-first
|
||||
npm --prefix web run test:library-archive-budget
|
||||
npm --prefix web run test:library-archive-conflicts
|
||||
npm --prefix web run test:library-archive-cancellation
|
||||
node --test web/tests/unit/library-archive-recovery.test.mjs
|
||||
node tools/web/check-malicious-archive-fixtures.mjs
|
||||
npm --prefix web run test:vdb
|
||||
npm --prefix web run test:vdb-native
|
||||
```
|
||||
|
||||
@@ -25,13 +25,61 @@
|
||||
8. N-025-E(审计链):至多 65,536 条拒绝审计按 sequence、前项 SHA-256 与 canonical
|
||||
entry SHA-256 串联;读取时重新校验请求摘要和整条链,拒绝 requestId 重放、非递增 UTC
|
||||
时间戳、内容篡改、断链与超预算日志。该链是内存/序列化协议,不声称已持久化发布审计。
|
||||
9. M13-02A manifest gate:每个 script 必须声明 `sourceByteLength` 和 `module=false`;解析器限制
|
||||
脚本数量、总源码字节、依赖数量、权限数量与 allowlist,canonicalize 项目内 entry/dependency
|
||||
path,并拒绝重复依赖、模块执行、未知权限和所有预算溢出。Node unit 与生产 Chromium Worker
|
||||
正负例、golden report 和 artifact manifest 已绑定。
|
||||
10. M13-02B canonical signature input:`canonicalizeScriptingManifest` 与
|
||||
`serializeScriptingManifest` 是唯一规范入口,locale-independent code-unit 排序所有可重排
|
||||
数组,固定无空白 canonical JSON,unknown fields 不进入签名输入;order mutation、security
|
||||
field mutation 和 schema drift 均由 Node/Chromium 与 golden report 验证。
|
||||
11. M13-02C signer trust policy:版本化 trust policy 绑定 ED25519 key/public-key、publisher、
|
||||
active/revoked status、validity window、revocation timestamp、same-publisher rotation chain
|
||||
和 bounded clock skew;resolver 只返回 `ELIGIBLE/cryptographicVerification=REQUIRED`,不验签
|
||||
不执行,revoked/expired/mismatch/cycle/missing predecessor 全部 fail-closed。
|
||||
12. M13-02D declaration-bound signature verification:canonical per-script input 包含 source
|
||||
SHA-256 和权限/预算/路径等声明,合法 ED25519 signature 才返回 `VERIFIED`;source hash 或
|
||||
signature 变化返回 `SCRIPT_SIGNATURE_INVALID`,revoked signer 返回 `SCRIPT_POLICY_DENIED`。
|
||||
13. M13-02E permission minimization:无显式请求时授予空集;只有 manifest 已声明且请求的
|
||||
permission 才能授予,未知、重复或未声明请求稳定返回 `SCRIPT_POLICY_DENIED`。
|
||||
14. M13-02F signature negative matrix:missing/expired/not-yet-valid key、publisher confusion
|
||||
与跨脚本 signature swap 均稳定返回 `SCRIPT_POLICY_DENIED` 或 `SCRIPT_SIGNATURE_INVALID`,
|
||||
canonical ordering 不改变自身签名结果,且不开放执行入口。
|
||||
15. M13-03A sandbox scope contract:versioned scope 对 DOM、host Worker、OPFS、IndexedDB 和
|
||||
network 五项能力逐项要求 `false`;启用、缺失或未知 schema 均 fail-closed,执行仍禁用。
|
||||
16. M13-03B sandbox budget contract:CPU、wall-time、memory、message 和 output bytes 各有固定
|
||||
上限;任一超限返回 `SCRIPT_BUDGET_EXCEEDED`,不创建或启用脚本执行器。
|
||||
17. M13-03C host-call contract:仅允许五个显式调用名;每个调用使用结构化、调用专属参数,
|
||||
permission 必须来自 manifest 声明,未知字段、危险路径和未声明调用 fail-closed,解析结果
|
||||
保持 `execution=DISABLED`。
|
||||
18. M13-03D sandbox isolation:真实 Chromium Worker crash/timeout 后 job receipt 分别返回
|
||||
`SCRIPT_SANDBOX_CRASHED`/`SCRIPT_SANDBOX_TIMEOUT`,Main revision 不变,temporary/published
|
||||
资源归零;终止后的迟到结果返回 `SCRIPT_SANDBOX_LATE_RESULT`,执行仍为 `DISABLED`。
|
||||
19. M13-03E cancellation gate:取消 receipt 保持 Main revision 和 execution 状态,真实 Chromium
|
||||
迟到窗口 `lateMessages=0`、`cacheWrites=0`,伪造迟到结果稳定返回 `SCRIPT_SANDBOX_LATE_RESULT`。
|
||||
20. M13-03F dispose gate:真实 Chromium Worker 释放两端 `MessagePort`、timer、AbortController、
|
||||
transferable buffer、pending request 和 cache reference;首次和重复 dispose 均返回零资源,
|
||||
且迟到 timer 消息为 0。
|
||||
21. M13-03G same-session recovery:Worker generation 4->5 后 Main revision/source hash/manifest hash
|
||||
保持不变;两条 default-deny audit entry 的 request ID、sequence 和 previous hash chain 连续,
|
||||
replay/source tamper 均返回 `SCRIPT_MANIFEST_INVALID`。
|
||||
22. M13-04A server job directory gate:每个 job 获得随机 `0700` one-shot directory,request ID 不
|
||||
进入目录名;成功/失败清理后无残留且重复清理幂等。
|
||||
23. M13-04B source/output isolation:source directory/file 为 `0555/0444`,真实写入返回 `EACCES`;
|
||||
output directory 为 `0700` 且可写,清理会先恢复 source directory 权限并无残留。
|
||||
24. M13-04C server resource budget:CPU、memory、process、file、wall 和 output 六类限制有固定
|
||||
上限;每类超限均返回 `SERVER_JOB_BUDGET_EXCEEDED`,bounded receipt 标记 `enforced=true`,
|
||||
执行仍为 `DISABLED`。
|
||||
25. M13-04D server network policy:默认 network `DENY`;显式声明的 HTTPS/loopback origin 才可
|
||||
`ALLOWED`,missing/undeclared/unsafe origin 均为 `SERVER_NETWORK_DENIED`。
|
||||
|
||||
## 仍然阻断
|
||||
|
||||
- N-025-B/C:签名验证密钥管理、无网络 CPython/native sandbox、server Blender job 和
|
||||
output hash 提交。
|
||||
- N-025-D/E:真实 GPU/native window/file watcher 适配、恶意脚本/依赖混淆/逃逸/重放、
|
||||
审计日志持久化和发布门;本地请求级审计凭证已完成,不代表隔离执行完成。
|
||||
- N-025-D/E:真实 server isolation、真实 GPU/native
|
||||
window/file watcher 适配、恶意脚本/依赖混淆/逃逸/重放、审计日志持久化和发布门;本地
|
||||
请求级审计凭证与 crash/timeout receipt 已完成,不代表隔离执行完成。
|
||||
|
||||
## 验收
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user