224 lines
17 KiB
Markdown
224 lines
17 KiB
Markdown
# N-023 Asset、Library 与 IO
|
||
|
||
状态:`BLOCKED`(asset catalog、来源/许可证元数据、真实 Main library inventory、库依赖与
|
||
IO 安全门已落地;bounded Append Main 及其 canonical persistence 已完成,Link/Override Main、
|
||
非 GLB 本地导入和跨桌面重导入仍未实现)
|
||
|
||
## 完整对标盘点基线
|
||
|
||
M12-01A 已从 Blender 5.2 DNA、RNA、Blend IO、AssetCatalog/CDF 源码及真实 RNA runtime 盘点
|
||
14 个 `AssetMetaData` DNA 字段、10 个公开 RNA 属性、3 个 `AssetTag` 存储字段和 3 个 catalog
|
||
持久语义字段。M12-01B 随后用锁定 Blender 5.2 生成 3 条 CDF v1 catalog、Object/Material/World
|
||
资产和 canonical JSON,并由独立 Blender 新进程精确重开复验。M12-01C 以 Blender UUID/path
|
||
和 AssetWeakReference 定义 Web schema v2 stable identity,并冻结 UTF-8 文本及条目预算。三项均为
|
||
`enablingTask`。M12-01D 又完成 v1→v2 无损前向迁移,保留 revision、source、preview 与 library
|
||
graph,并输出确定性 ID mapping/hash report。四项只冻结完整对标输入与迁移,不增加本节已验证
|
||
slice。M12-01E 又固定 v2 对 v1 reader 的 read-only/write-block/future-reject 策略。五项仍不改变
|
||
`parityStatus=BLOCKED`。
|
||
|
||
M12-01F 已补齐 duplicate catalog/asset ID、legacy parent cycle、v2 parentPath drift、UTF-8
|
||
simple-name/tag budget 和 v1/v2 unknown-field 共 9 类稳定负例;该 enabling evidence 不改变 slice。
|
||
|
||
M12-01G 已让 v1→v2 IndexedDB index migration 在同一 readwrite transaction 中提交 target、
|
||
receipt 和 source delete;写 target 后或删 source 后注入失败均 abort,关闭并重开后旧 v1 index、
|
||
无关 migration 行和数据库版本精确不变。该 enabling evidence 仍不改变 slice。
|
||
|
||
M12-01H 又证明初始页面、reload 和两个顺序重建的独立 Worker 读取相同 catalog/asset 顺序、
|
||
AssetWeakReference stable identity、revision 和 manifest SHA-256;receipt/hash drift 在发布前阻断。
|
||
该 enabling evidence 仍不改变 slice。
|
||
|
||
M12-01I 将 A-H 八项任务链、Blender 5.2 desktop fixture、Web v2 fixture、production migration
|
||
report、canonical 双 hash 和 IndexedDB fault/restart artifact 递归绑定为一个 READY evidence。
|
||
M12.1 schema/migration 已收口,但仍是 enabling evidence,不把 catalog mutation/preview 计为完成。
|
||
|
||
M12-02A 已盘点 PreviewImage 的 ICON/PREVIEW 双槽、持久尺寸/rect/flag、RGBA8 packed pixel、
|
||
premultiplied alpha、runtime deferred/invalid 状态和真正的 null pointer。原生结构/RNA 没有颜色空间
|
||
字段;现有 Web v1/v2 也缺 slot/colorSpace/alpha/generator 语义。本项仍是 inventory evidence。
|
||
|
||
M12-02B 定义 source/content 各自的 byte length、MIME、SHA-256,并让 content 绑定尺寸、RGBA8、
|
||
sRGB/alpha profile,generator 绑定 Blender version/executable/script/settings。真实 Blender 两次重编码
|
||
确定性相同,source/content 编码不同但解码像素 exact;本项仍是 enabling identity evidence。
|
||
|
||
M12-02C 在任何图像 decoder 或 decoded allocation 前依次检查 identity、16 MiB encoded bytes、
|
||
content SHA-256、PNG/WebP header、identity-bound dimensions、16,777,216 pixels、64 MiB RGBA8
|
||
decoded bytes 和 100:1 compression ratio。8 类失败均 fail-closed,随后小 preview 可立即恢复;
|
||
本项仍是 enabling budget evidence,不把 preview storage/display 计为完成。
|
||
|
||
M12-02D 先把 content-addressed preview 写入 OPFS 并回读复验,再用一次 revision/full-row guarded
|
||
IndexedDB transaction 提交 catalog v2 preview reference 和 hash receipt。OPFS 前后及 catalog put
|
||
后的三处 fault 都保持旧 catalog;重开后 revision、receipt 和 payload hash 一致。本项仍不把
|
||
dedupe、损坏隔离或 viewport display 计为完成。
|
||
|
||
M12-02E 又让两个不同 Blender weak-reference identity 和不同 metadata 的 asset 共享相同 content
|
||
SHA-256;第二次写入只复验并复用 OPFS payload,物理文件计数为 1,两个 catalog entry 的完整
|
||
non-preview metadata 不变,revision 9 重开一致。本项仍不把损坏隔离或 display 计为完成。
|
||
|
||
M12-02F 将同长度但 SHA-256 漂移的 bytes 从 content-addressed namespace 移入复验后的 quarantine
|
||
文件,并写入与 catalog revision/reference 绑定的 receipt。catalog 本身及另一 asset 均不变;重开后
|
||
仍可读取完整 metadata,只把 preview/data 返回 null。本项仍不把 reference GC/display 计为完成。
|
||
|
||
M12-02G 在 catalog reference transaction 完成后按 committed manifest 计数:同项目仍有一个引用时
|
||
保留 payload,最后一个引用删除后才回收。OPFS project namespace 保证另一项目的同 hash payload
|
||
和 READY preview 不受影响;revision 11 重开 metadata 不变。本项仍不把 display 计为完成。
|
||
|
||
M12-02H 已把 Blender 5.2 确定性重编码的 `SRGB/RGBA8/STRAIGHT` preview 固定为逐字节 reference,
|
||
主线程 `HTMLCanvasElement` 与独立 Worker `OffscreenCanvas` 共用生产 decode/display 实现。两条路径
|
||
均先通过 M12-02C 的 identity/header/预算门,再以禁用色彩转换和预乘的 `ImageBitmap` 解码;输出
|
||
256-byte RGBA8 hash 与 desktop reference 完全一致,MAE/RMS/P95/max/bad-pixel/alpha 指标均为零,
|
||
前景 IoU 为 1。该项新增一个已验证 preview display parity slice,但不扩大到任意尺寸、色彩空间、
|
||
asset browser UI 或 Append/Link/Override。
|
||
|
||
M12-03A 已分别冻结 Append、Link 与 Library Override 的数据块/闭包边界。真实 Blender runtime
|
||
公开 36 类 selectable root,其中 Screen/WorkSpace 为 append-only;Library 是来源/传递依赖元数据,
|
||
Key 等 embedded ID 随 owner 进入闭包。Append 由实际 ID pointer graph 区分 direct、indirect、
|
||
cross-library、override dependency 与 reusable local;Link 保留 `ID.lib`、EXTERN/INDIRECT 和
|
||
`Library.runtime.parent`;Override 另记录 linked reference、local owner、hierarchy root、property/
|
||
operation 与 system dependency。该 inventory 仍不创建 ownership contract 或 Main transaction。
|
||
|
||
M12-03B 已定义 schema 1 library operation identity。`sourceLibraryId` 同时绑定 canonical source
|
||
locator 与 `.blend` SHA-256;APPEND 只能由 `LOCAL_MAIN` owner 持有且可写,LINK 只能由匹配的
|
||
`SOURCE_LIBRARY` owner 持有且 root/reference 均只读,LIBRARY_OVERRIDE 由 `LOCAL_OVERRIDE`
|
||
持有、local 可写但 linked reference 只读。invalidation token 还绑定 operation、root、owner、
|
||
source generation/revision 与 dependency-closure hash;任一漂移稳定返回 `REVISION_CONFLICT`。
|
||
|
||
M12-03C 已生成真实 Blender 5.2 desktop 单 Object append fixture。选中的 Object 自动带入 Mesh、
|
||
Material 和 packed Image 依赖,四个 ID 在 target Main 中均无 source library/override 指针并映射为
|
||
可写 `LOCAL_MAIN` owner。新 Blender load 路径重开 target 后,3 条依赖边、4/4/1 geometry、UVMap、
|
||
material slot、2x2 sRGB RGBA image 和 Float32 pixel SHA-256 均与 source canonical report 一致。
|
||
本项只冻结 desktop 权威 fixture,不提前声明 WASM Main append、undo/redo 或完整 append parity。
|
||
该合同没有提前执行 Append 或开放 writer。
|
||
|
||
M12-03D 已把同一 source-hash-bound closure 送入 WASM Worker 的 authoritative Blender Main。Native
|
||
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。
|
||
|
||
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。
|
||
|
||
## 已验证切片
|
||
|
||
1. N-023-A:版本化 manifest 覆盖 catalog、asset kind/tag、preview、author、license、
|
||
source path/SHA-256、library source/dependency/read-only metadata;重复 ID、缺 catalog、
|
||
缺许可证和哈希不匹配会拒绝。
|
||
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 可放行;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 数量/单项/总量、压缩展开比率均有边界。
|
||
6. N-023-B(部分):Blender 5.2 Main reader 输出 linked Library stable ID、项目相对路径、
|
||
packed/external 状态、只读标志和 archive-parent dependency;1024 library/每库 1024 dependency、
|
||
重复 ID、缺依赖、依赖环与项目外路径由 SceneIR 再校验。缺外部库字节时返回
|
||
`LINKED_LIBRARY_RESOURCE_REQUIRED`,不从路径伪造 SHA-256 或声称已加载。
|
||
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 原子
|
||
staging/commit、source/bundle binding、Worker 重开、tamper/rollback/quota recovery 和 bundle LRU
|
||
已完成;大 bundle 性能仍未实现。
|
||
9. VDB 独立资源库包含 generated/official/source/derived/report/manifest/license,14 条记录逐项绑定
|
||
byte length 与 SHA-256;官方 sphere 使用 CC-BY-4.0 和 Git LFS 权威 hash,未放入仓库工作树。
|
||
10. N-023-A(preview display):Blender 5.2 desktop RGBA8 reference、主线程 Canvas2D 与
|
||
OffscreenCanvas 的像素 SHA-256 精确一致;错误像素返回 `RENDER_REFERENCE_MISMATCH`。
|
||
|
||
## 仍然阻断
|
||
|
||
- 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/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 中断/内存性能门仍阻断。
|
||
|
||
## 验收
|
||
|
||
```bash
|
||
WEB_TEST_PORT=5323 npm --prefix web run test:e2e -- --grep "N-023 asset"
|
||
npm --prefix web run test:library-main-reader
|
||
npm --prefix web run test:asset-catalog-inventory
|
||
npm --prefix web run test:asset-catalog-v1-fixture
|
||
npm --prefix web run test:asset-catalog-v2
|
||
npm --prefix web run test:asset-catalog-migration
|
||
npm --prefix web run test:asset-catalog-legacy-reader
|
||
npm --prefix web run test:asset-catalog-negatives
|
||
npm --prefix web run test:asset-preview-inventory
|
||
npm --prefix web run test:asset-preview-identity
|
||
npm --prefix web run test:asset-preview-decode-budget
|
||
npm --prefix web run test:asset-preview-opfs-commit
|
||
npm --prefix web run test:asset-preview-dedup
|
||
npm --prefix web run test:asset-preview-quarantine
|
||
npm --prefix web run test:asset-preview-reference-gc
|
||
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
|
||
```
|