From c78b802be647604effcab5bb2942fba774d9418f Mon Sep 17 00:00:00 2001 From: mes123456 Date: Thu, 3 Sep 2026 18:35:08 +0800 Subject: [PATCH] chore(web): continuous handoff WBV2-P1159-001 --- docs/EXECUTION_QUEUE.md | 6 +- docs/status/WBV2-P1159-001.md | 9 + docs/tasks/WBV2-P1159-001.md | 45 + .../web/line_style_modifier_batch_scene.blend | Bin 0 -> 86107 bytes tests/golden/WBV2-P1159-000/manifest.json | 42 + .../WBV2-P1159-000/module-execution-plan.json | 7929 +++++++++++++++++ .../line-style-reader-production.json | 81 + tests/golden/WBV2-P1159-001/manifest.json | 99 + .../golden/WBV2-P1159-001/module-receipt.json | 125 + tests/golden/WBV2-P1159-001/module-run.log | 49 + tests/golden/WBV2-P1159-001/task-context.json | 187 + tests/golden/WBV2/task-catalog.jsonl | 2 + tests/golden/WBV2/task-index.json | 2 +- .../wbv2-line-style-reader-production.spec.ts | 10 +- 14 files changed, 8581 insertions(+), 5 deletions(-) create mode 100644 docs/status/WBV2-P1159-001.md create mode 100644 docs/tasks/WBV2-P1159-001.md create mode 100644 tests/files/web/line_style_modifier_batch_scene.blend create mode 100644 tests/golden/WBV2-P1159-000/manifest.json create mode 100644 tests/golden/WBV2-P1159-000/module-execution-plan.json create mode 100644 tests/golden/WBV2-P1159-001/line-style-reader-production.json create mode 100644 tests/golden/WBV2-P1159-001/manifest.json create mode 100644 tests/golden/WBV2-P1159-001/module-receipt.json create mode 100644 tests/golden/WBV2-P1159-001/module-run.log create mode 100644 tests/golden/WBV2-P1159-001/task-context.json diff --git a/docs/EXECUTION_QUEUE.md b/docs/EXECUTION_QUEUE.md index 9087ed0bb..30ff79616 100644 --- a/docs/EXECUTION_QUEUE.md +++ b/docs/EXECUTION_QUEUE.md @@ -15,9 +15,9 @@ | 字段 | 值 | | --- | --- | | 里程碑 | WBV2 capability workflow | -| 当前任务 | `WBV2-P1158-001` | -| parent manifest | `tests/golden/WBV2-P1158-000/manifest.json` | -| 任务卡 | [`tasks/WBV2-P1158-001.md`](tasks/WBV2-P1158-001.md) | +| 当前任务 | `WBV2-P1159-001` | +| parent manifest | `tests/golden/WBV2-P1159-000/manifest.json` | +| 任务卡 | [`tasks/WBV2-P1159-001.md`](tasks/WBV2-P1159-001.md) | | 专项验收 | `node tools/web/check-execution-control-plane.mjs` | | legacy coverage checkpoint | `M16-GAP-00282` | | legacy coverage parent | `tests/golden/M16-GAP-00281/manifest.json` | diff --git a/docs/status/WBV2-P1159-001.md b/docs/status/WBV2-P1159-001.md new file mode 100644 index 000000000..8376a604d --- /dev/null +++ b/docs/status/WBV2-P1159-001.md @@ -0,0 +1,9 @@ +# WBV2-P1159-001 status + +- task: `WBV2-P1159-001`; module: `LINE_STYLE_COLLECTION_READER_BATCH`; status: `done` +- source hashes stable: `true`; commands passed: `4` +- existing production evidence reused: `false`; skipped commands: `0` +- positive Main mutation, negative no-mutation, recovery and Chromium gates are recorded in the module receipt +- dynamic source inventory: `3745` units; verified `478`; unverified `3267`; planning estimate `5200` (non-binding); this-segment binding delta: `5` +- historical 6900-entry inventory remains read-only; full-family parity: `false` +- nextTask: `NONE` diff --git a/docs/tasks/WBV2-P1159-001.md b/docs/tasks/WBV2-P1159-001.md new file mode 100644 index 000000000..5622261a5 --- /dev/null +++ b/docs/tasks/WBV2-P1159-001.md @@ -0,0 +1,45 @@ +# WBV2-P1159-001: verify line style collection reader batch + +- task: WBV2-P1159-001 +- parent: WBV2-P1159-000 +- status: in_progress +- gap: capability:LINE_STYLE_COLLECTION_READER_BATCH +- ownerFamily: DRAWING +- targetImplementationClass: LOCAL_EXACT +- Implementation entrypoint: `node tools/web/run-wbv2-module-task.mjs --task WBV2-P1159-001 --write` + +## 目标 + +以一个共享 Blender Main reader、WASM build、Worker 路由和 Chromium receipt 批量验证 RNA-only reader units 的真实 modifier/RNA 元数据。 + +## 输入与范围 + +- Blender modifier sources: `blender-5.2.0/source/blender/modifiers/intern/` +- RNA source: `blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc` +- Native reader: `blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp` +- Fixtures: `tests/files/web/line_style_modifier_batch_scene.blend` +- Chromium test: `web/tests/e2e/wbv2-line-style-reader-production.spec.ts` +- Selected modifier units: none +- Selected RNA units: `rna-struct:BlendDataLineStyles`, `rna-struct:LineStyleColorModifiers`, `rna-struct:LineStyleAlphaModifiers`, `rna-struct:LineStyleThicknessModifiers`, `rna-struct:LineStyleGeometryModifiers` + +## 验收 + +- one shared Main/WASM/Worker/Chromium chain observes every selected type +- malformed input is rejected without Main mutation +- save/reopen and deterministic second read are exact +- only Chromium is used; JS simulation and per-API duplicate workers are forbidden +- each selected source unit receives an explicit hash-bound coverage binding +- `node tools/web/check-task-context.mjs --task WBV2-P1159-001 --write` + +## 失败边界 + +- any missing source, unsupported type, hash drift, malformed data or non-exact recovery keeps the batch `in_progress`/`blocked` +- partial batch success never claims the omitted family; historical inventory remains read-only + +## 交付与回滚 + +- Receipt: `tests/golden/WBV2-P1159-001/module-receipt.json` +- Aggregate production evidence: `tests/golden/WBV2-P1159-001/modifier-reader-batch-production.json` +- Manifest: `tests/golden/WBV2-P1159-001/manifest.json` +- Status: `docs/status/WBV2-P1159-001.md` +- Rollback: restore WBV2-P1159-000 as queue parent without rewriting prior evidence. diff --git a/tests/files/web/line_style_modifier_batch_scene.blend b/tests/files/web/line_style_modifier_batch_scene.blend new file mode 100644 index 0000000000000000000000000000000000000000..f3757ae37393de6955732682a75980e9127068d7 GIT binary patch literal 86107 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

KfBpmME$_|c15VlVTyXijB)%rt;i}+8^fI{D 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 T?EnB64gvrJ00000vFehK7hWWW literal 0 HcmV?d00001 diff --git a/tests/golden/WBV2-P1159-000/manifest.json b/tests/golden/WBV2-P1159-000/manifest.json new file mode 100644 index 000000000..dcc041049 --- /dev/null +++ b/tests/golden/WBV2-P1159-000/manifest.json @@ -0,0 +1,42 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P1159-000", + "parentTask": "WBV2-P1158-001", + "operation": "AUTHORIZE_SOURCE_BACKED_MODULE_BATCH", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "MODULE_EXECUTION_QUEUE_BRIDGE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P1158-001/manifest.json", + "sha256": "519d51cd20282b5ca941ab33ae359e06ac33a034f216805275f1f58fb05a2556" + }, + "plan": { + "path": "tests/golden/WBV2-P1159-000/module-execution-plan.json", + "sha256": "5ab51feaee1b61853baa68a40b68c665a51a3cb2643ec3d361795fa5fe4663a6" + }, + "report": { + "path": "tests/golden/WBV2-P1159-000/successor-authorization-report.json", + "sha256": "7f3e99e215c9c53b93609adaf52db805959d86c8e5de59efbda80c7da31f501a" + }, + "status": { + "path": "docs/status/WBV2-P1159-000.md", + "sha256": "d08be511beee193662783943956094e4f01be166bc8ce1dbfc76125f6546ba77" + } + }, + "assertions": { + "sourceBackedSuccessor": true, + "moduleId": "LINE_STYLE_COLLECTION_READER_BATCH", + "batchSize": 5, + "inventoryTotal": 6900, + "effectiveCompleted": 290, + "effectivePending": 6609, + "dynamicUnitCount": 3745, + "dynamicVerifiedUnits": 473, + "dynamicUnverifiedUnits": 3272, + "boundUnitDelta": 0, + "fullHistoricalReproduction": false + }, + "nextTask": "WBV2-P1159-001" +} diff --git a/tests/golden/WBV2-P1159-000/module-execution-plan.json b/tests/golden/WBV2-P1159-000/module-execution-plan.json new file mode 100644 index 000000000..b32101702 --- /dev/null +++ b/tests/golden/WBV2-P1159-000/module-execution-plan.json @@ -0,0 +1,7929 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_MODULE_EXECUTION_P1159", + "operation": "FUNCTION_MODULE_MIGRATION_PLAN", + "status": "COMPLETED_MODULE_EXECUTION", + "authority": "blender_main_source_and_existing_hash_bound_receipts", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "inventory": { + "path": "tests/golden/WBV2-P0-002/parity-map.json", + "sha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8", + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "mutation": "forbidden_by_module_execution" + }, + "reusePolicy": { + "completedReceipts": "reuse_without_rerun", + "continuationEvidence": "excluded", + "duplicateValidation": "forbidden", + "fullFamilyParity": "never_inferred" + }, + "verificationPolicy": { + "browser": "chromium_only", + "required": [ + "sourceHash", + "wasmBuild", + "positiveMainMutation", + "negativeNoMutation", + "undoRedo", + "saveReopen", + "aggregateManifest" + ], + "failure": "keep_module_in_progress_and_do_not_advance" + }, + "modules": [ + { + "id": "RENDER_LIGHT_CAMERA", + "task": "WBV2-P1100-001", + "owner": "RENDER", + "sourceBacked": true, + "capabilities": [ + "CAP-RENDER-LIGHT-TYPE", + "CAP-RENDER-LIGHT-AREA-SHAPE", + "CAP-RENDER-LIGHT-CONTRIBUTION-FACTORS", + "CAP-RENDER-LIGHT-SHADOW-CONTROLS", + "CAP-RENDER-LIGHT-CASCADE-CONTROLS", + "CAP-RENDER-LIGHT-AREA-SIZE-Z", + "CAP-RENDER-LIGHT-CLIP-START", + "CAP-RENDER-WORLD-LIGHTING-CONTROLS", + "CAP-RENDER-WORLD-PROBE-CONTROLS", + "CAP-RENDER-WORLD-ENVIRONMENT-STRENGTH", + "CAP-RENDER-CAMERA-DOF-FOCUS-OBJECT", + "CAP-RENDER-CAMERA-PANORAMA" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P595-002/manifest.json", + "report": "tests/golden/WBV2-P595-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P596-002/manifest.json", + "report": "tests/golden/WBV2-P596-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P597-002/manifest.json", + "report": "tests/golden/WBV2-P597-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P598-002/manifest.json", + "report": "tests/golden/WBV2-P598-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P599-002/manifest.json", + "report": "tests/golden/WBV2-P599-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P600-002/manifest.json", + "report": "tests/golden/WBV2-P600-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P601-002/manifest.json", + "report": "tests/golden/WBV2-P601-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P602-002/manifest.json", + "report": "tests/golden/WBV2-P602-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P603-002/manifest.json", + "report": "tests/golden/WBV2-P603-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P604-002/manifest.json", + "report": "tests/golden/WBV2-P604-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P605-002/manifest.json", + "report": "tests/golden/WBV2-P605-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P606-002/manifest.json", + "report": "tests/golden/WBV2-P606-002/implementation-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "SCENE_OBJECT_MESH", + "task": "WBV2-P1100-002", + "owner": "SCENE_MESH", + "sourceBacked": true, + "capabilities": [ + "CAP-MESH-TOPOLOGY-FAMILY", + "CAP-CORE-SCENE-OBJECT", + "CAP-OBJECT-MOVE-COLLECTION" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P11-001/manifest.json", + "report": "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P12-002/manifest.json", + "report": "tests/golden/WBV2-P12-002/scene-object-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P24-002/manifest.json", + "report": "tests/golden/WBV2-P24-002/object-move-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MATERIAL_ANIMATION", + "task": "WBV2-P1100-003", + "owner": "MATERIAL_ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-MATERIAL-ANIMATION" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P12-003/manifest.json", + "report": "tests/golden/WBV2-P12-003/material-animation-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "NONMESH_GEOMETRY", + "task": "WBV2-P1101-000", + "owner": "GEOMETRY", + "sourceBacked": true, + "capabilities": [ + "CAP-VIEWPORT-NONMESH", + "CAP-NATIVE-DATABLOCK" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P12-004/manifest.json", + "report": "tests/golden/WBV2-P12-004/viewport-nonmesh-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P29-003/manifest.json", + "report": "tests/golden/WBV2-P29-003/implementation-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "NODES_SIMULATION", + "task": "WBV2-P1101-001", + "owner": "NODES_SIMULATION", + "sourceBacked": true, + "capabilities": [ + "CAP-GEOMETRY-NODES", + "CAP-SIMULATION" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-002/manifest.json", + "report": "tests/golden/WBV2-P13-002/geometry-nodes-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "ASSET_IO", + "task": "WBV2-P1101-002", + "owner": "ASSET", + "sourceBacked": true, + "capabilities": [ + "CAP-ASSET-LINK-OVERRIDE-RELOAD", + "CAP-ASSET-CATALOG-MUTATION" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P11-003/manifest.json", + "report": "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P10-003/manifest.json", + "report": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "SCULPT_PAINT", + "task": "WBV2-P1101-003", + "owner": "SCULPT_PAINT", + "sourceBacked": true, + "capabilities": [ + "CAP-PAINT-ATTRIBUTES", + "CAP-SCULPT-PAINT" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P16-002/manifest.json", + "report": "tests/golden/WBV2-P16-002/paint-attributes-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "UI_EDITOR", + "task": "WBV2-P1102-000", + "owner": "EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-UI-EDITOR" + ], + "reusedReceipts": [], + "fullFamilyParity": false + }, + { + "id": "INVENTORY_GATE", + "task": "WBV2-P1102-001", + "owner": "RELEASE", + "sourceBacked": true, + "capabilities": [], + "reusedReceipts": [], + "fullFamilyParity": false + }, + { + "id": "OBJECT_OPERATIONS", + "task": "WBV2-P1103-000", + "owner": "OBJECT", + "sourceBacked": true, + "capabilities": [ + "CAP-OBJECT-DUPLICATE", + "CAP-OBJECT-CREATE", + "CAP-OBJECT-PARENT", + "CAP-OBJECT-COLLECTION", + "CAP-OBJECT-RENAME", + "CAP-OBJECT-DELETE", + "CAP-OBJECT-TRANSFORM" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P17-002/manifest.json", + "report": "tests/golden/WBV2-P17-002/object-duplicate-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P18-002/manifest.json", + "report": "tests/golden/WBV2-P18-002/object-create-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P19-002/manifest.json", + "report": "tests/golden/WBV2-P19-002/object-parent-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P20-002/manifest.json", + "report": "tests/golden/WBV2-P20-002/collection-create-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P21-002/manifest.json", + "report": "tests/golden/WBV2-P21-002/object-rename-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P22-002/manifest.json", + "report": "tests/golden/WBV2-P22-002/object-delete-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P23-002/manifest.json", + "report": "tests/golden/WBV2-P23-002/object-transform-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "COMPOSITOR_SEQUENCER", + "task": "WBV2-P1104-000", + "owner": "MEDIA", + "sourceBacked": true, + "capabilities": [ + "CAP-COMPOSITOR-NODE-GRAPH", + "CAP-COMPOSITOR-UNSUPPORTED-GATE", + "CAP-SEQUENCER-MEDIA-RECOVERY" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P29-003/manifest.json", + "report": "tests/golden/WBV2-P29-003/implementation-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "AUDIO_PARTICLE", + "task": "WBV2-P1105-000", + "owner": "AUDIO_PARTICLE", + "sourceBacked": true, + "capabilities": [ + "CAP-SOUND-PROPERTIES", + "CAP-SPEAKER-PROPERTIES", + "CAP-PARTICLE-SETTINGS" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P33-001/manifest.json", + "report": "tests/golden/WBV2-P33-001/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P33-002/manifest.json", + "report": "tests/golden/WBV2-P33-002/implementation-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "RIG_ANIMATION", + "task": "WBV2-P1106-000", + "owner": "RIG", + "sourceBacked": true, + "capabilities": [ + "CAP-RIG-POSE", + "CAP-CONSTRAINTS", + "CAP-NLA-ANIMATION" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-003/manifest.json", + "report": "tests/golden/WBV2-P13-003/rig-pose-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "CORE_SCENE_GRAPH_SETTINGS", + "task": "WBV2-P1129-001", + "owner": "CORE_SCENE", + "sourceBacked": true, + "capabilities": [ + "CAP-SCENE-COMPOSITOR-SETTINGS", + "CAP-SCENE-PERFORMANCE-SETTINGS", + "CAP-SCENE-SAMPLING-SETTINGS" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P65-002/manifest.json", + "report": "tests/golden/WBV2-P65-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P66-002/manifest.json", + "report": "tests/golden/WBV2-P66-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P67-002/manifest.json", + "report": "tests/golden/WBV2-P67-002/implementation-report.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "UI_EDITOR_VIEW2D_STATE", + "task": "WBV2-P1130-001", + "owner": "EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-EDITOR-VIEW2D-CUR", + "CAP-EDITOR-VIEW2D-MASK", + "CAP-EDITOR-VIEW2D-FAIL-CLOSED" + ], + "reusedReceipts": [], + "fullFamilyParity": false + }, + { + "id": "CURVE_TOPOLOGY_EDITOR", + "task": "WBV2-P1131-001", + "owner": "EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-TOPOLOGY-TOGGLE-CYCLIC", + "CAP-CURVE-TOPOLOGY-GATE", + "CAP-CURVE-TOPOLOGY-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/M9-05/manifest.json", + "report": "tests/golden/M9-05/curve-toggle-cyclic.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "CURVE_HANDLE_GIZMO", + "task": "WBV2-P1132-001", + "owner": "EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-HANDLE-MAIN", + "CAP-CURVE-HANDLE-GIZMO-PREVIEW", + "CAP-CURVE-HANDLE-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "CURVE_SPLINES_TRANSACTION", + "task": "WBV2-P1133-001", + "owner": "EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-SPLINES-MAIN", + "CAP-CURVE-SPLINES-RECOVERY", + "CAP-CURVE-SPLINES-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "SURFACE_TOPOLOGY_TRANSACTION", + "task": "WBV2-P1134-001", + "owner": "GEOMETRY", + "sourceBacked": true, + "capabilities": [ + "CAP-SURFACE-TOPOLOGY-MAIN", + "CAP-SURFACE-NURBS-BOUNDS", + "CAP-SURFACE-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "FONT_BODY_TRANSACTION", + "task": "WBV2-P1135-001", + "owner": "GEOMETRY", + "sourceBacked": true, + "capabilities": [ + "CAP-FONT-BODY-MAIN", + "CAP-FONT-BODY-RECOVERY", + "CAP-FONT-BODY-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "FONT_PROPERTIES_TRANSACTION", + "task": "WBV2-P1136-001", + "owner": "GEOMETRY", + "sourceBacked": true, + "capabilities": [ + "CAP-FONT-PROPERTIES-MAIN", + "CAP-FONT-PROPERTIES-RECOVERY", + "CAP-FONT-PROPERTIES-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "METABALL_ELEMENTS_TRANSACTION", + "task": "WBV2-P1137-001", + "owner": "GEOMETRY", + "sourceBacked": true, + "capabilities": [ + "CAP-METABALL-ELEMENTS-MAIN", + "CAP-METABALL-ELEMENTS-RECOVERY", + "CAP-METABALL-ELEMENTS-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "TEXT_SOURCE_TRANSACTION", + "task": "WBV2-P1138-001", + "owner": "SCRIPTING", + "sourceBacked": true, + "capabilities": [ + "CAP-TEXT-SOURCE-MAIN", + "CAP-TEXT-SOURCE-RECOVERY", + "CAP-TEXT-SOURCE-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1137-001/manifest.json", + "report": "tests/golden/WBV2-P1137-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "TEXTURE_PROPERTIES_TRANSACTION", + "task": "WBV2-P1139-001", + "owner": "TEXTURE", + "sourceBacked": true, + "capabilities": [ + "CAP-TEXTURE-PROPERTIES-MAIN", + "CAP-TEXTURE-PROPERTIES-RECOVERY", + "CAP-TEXTURE-PROPERTIES-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1138-001/manifest.json", + "report": "tests/golden/WBV2-P1138-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "ACTION_GROUP_READER", + "task": "WBV2-P1140-001", + "owner": "ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-ACTION-GROUP-READER", + "CAP-ACTION-GROUP-RECOVERY", + "CAP-ACTION-GROUP-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1112-000/manifest.json", + "report": "tests/golden/WBV2-P1112-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "ACTION_POSE_MARKERS_READER", + "task": "WBV2-P1141-001", + "owner": "ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-ACTION-POSE-MARKERS-READER", + "CAP-ACTION-POSE-MARKERS-RECOVERY", + "CAP-ACTION-POSE-MARKERS-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1140-001/manifest.json", + "report": "tests/golden/WBV2-P1140-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "FCURVE_SAMPLE_READER", + "task": "WBV2-P1142-001", + "owner": "ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-FCURVE-SAMPLE-READER", + "CAP-FCURVE-SAMPLE-RECOVERY", + "CAP-FCURVE-SAMPLE-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1141-001/manifest.json", + "report": "tests/golden/WBV2-P1141-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "FCURVE_MODIFIER_READER", + "task": "WBV2-P1143-001", + "owner": "ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-FCURVE-MODIFIER-READER", + "CAP-FCURVE-MODIFIER-RECOVERY", + "CAP-FCURVE-MODIFIER-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1142-001/manifest.json", + "report": "tests/golden/WBV2-P1142-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "DRIVER_READER", + "task": "WBV2-P1144-001", + "owner": "ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-DRIVER-READER", + "CAP-DRIVER-RECOVERY", + "CAP-DRIVER-FAIL-CLOSED" + ], + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1143-001/manifest.json", + "report": "tests/golden/WBV2-P1143-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "CORRECTIVE_SMOOTH_READER", + "task": "WBV2-P1145-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-CORRECTIVE-SMOOTH-READER", + "CAP-CORRECTIVE-SMOOTH-RECOVERY", + "CAP-CORRECTIVE-SMOOTH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_correctivesmooth.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-corrective-smooth-reader-production.spec.ts", + "tests/files/web/modifier_corrective_smooth_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_READER_BATCH", + "task": "WBV2-P1146-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH-READER", + "CAP-MODIFIER_READER_BATCH-RECOVERY", + "CAP-MODIFIER_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_datatransfer.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_dynamicpaint.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_explode.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_fluid.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_fluid.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-production.spec.ts", + "tests/files/web/modifier_reader_batch_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_READER_BATCH_TWO", + "task": "WBV2-P1147-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_TWO-READER", + "CAP-MODIFIER_READER_BATCH_TWO-RECOVERY", + "CAP-MODIFIER_READER_BATCH_TWO-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_laplaciandeform.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_laplaciansmooth.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_mask.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_shrinkwrap.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_two_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_READER_BATCH_THREE", + "task": "WBV2-P1148-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_THREE-READER", + "CAP-MODIFIER_READER_BATCH_THREE-RECOVERY", + "CAP-MODIFIER_READER_BATCH_THREE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_remesh.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_skin.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weighted_normal.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_warp.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_three_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_READER_BATCH_FOUR", + "task": "WBV2-P1149-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_FOUR-READER", + "CAP-MODIFIER_READER_BATCH_FOUR-RECOVERY", + "CAP-MODIFIER_READER_BATCH_FOUR-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_uvproject.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_uvwarp.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_normal_edit.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_volume_to_mesh.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_four_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_READER_BATCH_FIVE", + "task": "WBV2-P1150-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_FIVE-READER", + "CAP-MODIFIER_READER_BATCH_FIVE-RECOVERY", + "CAP-MODIFIER_READER_BATCH_FIVE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshsequencecache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_multires.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_ocean.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_five_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "GREASE_PENCIL_MODIFIER_READER_BATCH", + "task": "WBV2-P1151-001", + "owner": "DRAWING", + "sourceBacked": true, + "capabilities": [ + "CAP-GREASE_PENCIL_MODIFIER_READER_BATCH-READER", + "CAP-GREASE_PENCIL_MODIFIER_READER_BATCH-RECOVERY", + "CAP-GREASE_PENCIL_MODIFIER_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_armature.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_array.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_build.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_color.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_dash.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_envelope.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_hook.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_lattice.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_length.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_mirror.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_multiply.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_noise.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_offset.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_opacity.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_outline.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_shrinkwrap.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_simplify.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_smooth.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_subdiv.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_texture.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_thickness.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_time.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_tint.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_weight_angle.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_weight_proximity.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_grease_pencil_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_READER_BATCH_SIX", + "task": "WBV2-P1152-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_SIX-READER", + "CAP-MODIFIER_READER_BATCH_SIX-RECOVERY", + "CAP-MODIFIER_READER_BATCH_SIX-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_mesh_to_volume.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_particleinstance.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_surface.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgedit.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgmix.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgproximity.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/generated/M16-GAP-00081-modifier-MESH_TO_VOLUME.blend", + "tests/files/web/generated/M16-GAP-00087-modifier-PARTICLE_INSTANCE.blend", + "tests/files/web/generated/M16-GAP-00098-modifier-SURFACE.blend", + "tests/files/web/generated/M16-GAP-00103-modifier-VERTEX_WEIGHT_EDIT.blend", + "tests/files/web/generated/M16-GAP-00104-modifier-VERTEX_WEIGHT_MIX.blend", + "tests/files/web/generated/M16-GAP-00105-modifier-VERTEX_WEIGHT_PROXIMITY.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_SOURCE_DEPENDENCY_REUSE", + "task": "WBV2-P1153-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_SOURCE_DEPENDENCY_REUSE-READER", + "CAP-MODIFIER_SOURCE_DEPENDENCY_REUSE-RECOVERY", + "CAP-MODIFIER_SOURCE_DEPENDENCY_REUSE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_util.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache_mdd.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache_pc2.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache_util.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvg_util.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_array.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgedit.cc", + "tests/golden/WBV2-P1151-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1152-001/modifier-reader-batch-production.json", + "tools/web/reuse-wbv2-source-dependencies.mjs" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1150-001/manifest.json", + "report": "tests/golden/WBV2-P1150-001/module-receipt.json" + }, + { + "manifest": "tests/golden/WBV2-P1151-001/manifest.json", + "report": "tests/golden/WBV2-P1151-001/module-receipt.json" + }, + { + "manifest": "tests/golden/WBV2-P1152-001/manifest.json", + "report": "tests/golden/WBV2-P1152-001/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_SOLIDIFY_DEPENDENCY_REUSE", + "task": "WBV2-P1154-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_SOLIDIFY_DEPENDENCY_REUSE-READER", + "CAP-MODIFIER_SOLIDIFY_DEPENDENCY_REUSE-RECOVERY", + "CAP-MODIFIER_SOLIDIFY_DEPENDENCY_REUSE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_solidify_extrude.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_solidify.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_solidify.cc", + "tests/golden/WBV2-P1107-000/modifier-source-roundtrip-production.json", + "tests/golden/WBV2-P1107-000/modifier-source-roundtrip-production.json", + "tools/web/reuse-wbv2-source-dependencies.mjs" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/modifier-source-roundtrip-production.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_RNA_READER_BATCH", + "task": "WBV2-P1155-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_RNA_READER_BATCH-READER", + "CAP-MODIFIER_RNA_READER_BATCH-RECOVERY", + "CAP-MODIFIER_RNA_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/modifier_grease_pencil_scene.blend", + "tests/files/web/generated/M16-GAP-00088-modifier-PARTICLE_SYSTEM.blend", + "tests/files/web/generated/M16-GAP-00041-modifier-DECIMATE.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "MODIFIER_VOLUME_DISPLACE_BATCH", + "task": "WBV2-P1156-001", + "owner": "MODIFIER", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_VOLUME_DISPLACE_BATCH-READER", + "CAP-MODIFIER_VOLUME_DISPLACE_BATCH-RECOVERY", + "CAP-MODIFIER_VOLUME_DISPLACE_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_volume_displace.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/generated/M16-GAP-00106-modifier-VOLUME_DISPLACE.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "SHAPE_KEY_POINT_READER_BATCH", + "task": "WBV2-P1157-001", + "owner": "ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-SHAPE_KEY_POINT_READER_BATCH-READER", + "CAP-SHAPE_KEY_POINT_READER_BATCH-RECOVERY", + "CAP-SHAPE_KEY_POINT_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_key.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-shape-key-reader-production.spec.ts", + "tests/files/web/rigged_shape_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "LINE_STYLE_READER_BATCH", + "task": "WBV2-P1158-001", + "owner": "DRAWING", + "sourceBacked": true, + "capabilities": [ + "CAP-LINE_STYLE_READER_BATCH-READER", + "CAP-LINE_STYLE_READER_BATCH-RECOVERY", + "CAP-LINE_STYLE_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "tests/files/web/generated/M16-GAP-00008-datablock-FreestyleLineStyle.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + }, + { + "id": "LINE_STYLE_COLLECTION_READER_BATCH", + "task": "WBV2-P1159-001", + "owner": "DRAWING", + "sourceBacked": true, + "capabilities": [ + "CAP-LINE_STYLE_COLLECTION_READER_BATCH-READER", + "CAP-LINE_STYLE_COLLECTION_READER_BATCH-RECOVERY", + "CAP-LINE_STYLE_COLLECTION_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_main_api.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "tests/files/web/line_style_modifier_batch_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "fullFamilyParity": false + } + ], + "tasks": [ + { + "id": "WBV2-P1096-000", + "phase": "1096", + "title": "supersede_generic_continuation_queue", + "kind": "bridge", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1095-003" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "bridge", + "gate": "QUEUE", + "card": "docs/tasks/WBV2-P1096-000.md", + "behavior": "Replace the generic continuation queue with a finite module execution plan without claiming capability parity.", + "outputs": [ + "bridge manifest", + "status" + ], + "acceptance": [ + "no parity claim", + "inventory preserved", + "module plan hash-bound" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1100-000", + "phase": "1100", + "title": "reorganize_module_execution_plan", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1096-000" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1100-000.md", + "behavior": "Reuse completed source-backed work and activate finite module-level implementation and verification.", + "outputs": [ + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "completed receipts reused", + "generic continuation excluded", + "one module active", + "inventory preserved" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1100-001", + "phase": "1100", + "title": "verify_render_light_camera_module", + "kind": "module", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P1100-000" + ], + "parityId": "RENDER_LIGHT_CAMERA", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-render_light_camera", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1100-001.md", + "behavior": "Complete the RENDER_LIGHT_CAMERA module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "RENDER_LIGHT_CAMERA", + "sourceBacked": true, + "capabilities": [ + "CAP-RENDER-LIGHT-TYPE", + "CAP-RENDER-LIGHT-AREA-SHAPE", + "CAP-RENDER-LIGHT-CONTRIBUTION-FACTORS", + "CAP-RENDER-LIGHT-SHADOW-CONTROLS", + "CAP-RENDER-LIGHT-CASCADE-CONTROLS", + "CAP-RENDER-LIGHT-AREA-SIZE-Z", + "CAP-RENDER-LIGHT-CLIP-START", + "CAP-RENDER-WORLD-LIGHTING-CONTROLS", + "CAP-RENDER-WORLD-PROBE-CONTROLS", + "CAP-RENDER-WORLD-ENVIRONMENT-STRENGTH", + "CAP-RENDER-CAMERA-DOF-FOCUS-OBJECT", + "CAP-RENDER-CAMERA-PANORAMA" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P595-002/manifest.json", + "report": "tests/golden/WBV2-P595-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P596-002/manifest.json", + "report": "tests/golden/WBV2-P596-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P597-002/manifest.json", + "report": "tests/golden/WBV2-P597-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P598-002/manifest.json", + "report": "tests/golden/WBV2-P598-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P599-002/manifest.json", + "report": "tests/golden/WBV2-P599-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P600-002/manifest.json", + "report": "tests/golden/WBV2-P600-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P601-002/manifest.json", + "report": "tests/golden/WBV2-P601-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P602-002/manifest.json", + "report": "tests/golden/WBV2-P602-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P603-002/manifest.json", + "report": "tests/golden/WBV2-P603-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P604-002/manifest.json", + "report": "tests/golden/WBV2-P604-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P605-002/manifest.json", + "report": "tests/golden/WBV2-P605-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P606-002/manifest.json", + "report": "tests/golden/WBV2-P606-002/implementation-report.json" + } + ], + "positive": [ + "setLightProperties", + "setWorldProperties", + "setCameraProperties", + "camera panorama", + "world environment", + "light shadow/cascade" + ], + "negative": [ + "invalid enum", + "invalid numeric bounds", + "near/far conflict", + "unknown target", + "stale revision" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker disposal" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run test:lighting-field-roundtrip", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-lighting-fields-production.spec.ts tests/e2e/lighting-field-roundtrip.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1100-002", + "phase": "1100", + "title": "verify_scene_object_mesh_module", + "kind": "module", + "owner": "SCENE_MESH", + "dependsOn": [ + "WBV2-P1100-001" + ], + "parityId": "SCENE_OBJECT_MESH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-scene_object_mesh", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1100-002.md", + "behavior": "Complete the SCENE_OBJECT_MESH module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SCENE_OBJECT_MESH", + "sourceBacked": true, + "capabilities": [ + "CAP-MESH-TOPOLOGY-FAMILY", + "CAP-CORE-SCENE-OBJECT", + "CAP-OBJECT-MOVE-COLLECTION" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P11-001/manifest.json", + "report": "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P12-002/manifest.json", + "report": "tests/golden/WBV2-P12-002/scene-object-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P24-002/manifest.json", + "report": "tests/golden/WBV2-P24-002/object-move-receipt-report.json" + } + ], + "positive": [ + "mesh topology", + "visibility", + "transform", + "collection membership" + ], + "negative": [ + "invalid selection", + "stale revision", + "linked data" + ], + "recovery": [ + "undo", + "redo", + "save/reopen" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-topology-production.spec.ts tests/e2e/wbv2-scene-object-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1100-003", + "phase": "1100", + "title": "verify_material_animation_module", + "kind": "module", + "owner": "MATERIAL_ANIMATION", + "dependsOn": [ + "WBV2-P1100-002" + ], + "parityId": "MATERIAL_ANIMATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-material_animation", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1100-003.md", + "behavior": "Complete the MATERIAL_ANIMATION module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MATERIAL_ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-MATERIAL-ANIMATION" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P12-003/manifest.json", + "report": "tests/golden/WBV2-P12-003/material-animation-receipt-report.json" + } + ], + "positive": [ + "principled material", + "image node", + "keyframe", + "FCurve" + ], + "negative": [ + "unsupported graph", + "stale revision" + ], + "recovery": [ + "undo", + "redo", + "save/reopen" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-material-animation-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1101-000", + "phase": "1101", + "title": "verify_nonmesh_geometry_module", + "kind": "module", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P1100-003" + ], + "parityId": "NONMESH_GEOMETRY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-nonmesh_geometry", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1101-000.md", + "behavior": "Complete the NONMESH_GEOMETRY module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "NONMESH_GEOMETRY", + "sourceBacked": true, + "capabilities": [ + "CAP-VIEWPORT-NONMESH", + "CAP-NATIVE-DATABLOCK" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P12-004/manifest.json", + "report": "tests/golden/WBV2-P12-004/viewport-nonmesh-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P29-003/manifest.json", + "report": "tests/golden/WBV2-P29-003/implementation-report.json" + } + ], + "positive": [ + "curve", + "surface", + "font", + "volume", + "metaball", + "grease pencil" + ], + "negative": [ + "unsupported data", + "resource missing", + "malformed geometry" + ], + "recovery": [ + "save/reopen", + "resource disposal" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-viewport-nonmesh-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1101-001", + "phase": "1101", + "title": "verify_nodes_simulation_module", + "kind": "module", + "owner": "NODES_SIMULATION", + "dependsOn": [ + "WBV2-P1101-000" + ], + "parityId": "NODES_SIMULATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-nodes_simulation", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1101-001.md", + "behavior": "Complete the NODES_SIMULATION module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "NODES_SIMULATION", + "sourceBacked": true, + "capabilities": [ + "CAP-GEOMETRY-NODES", + "CAP-SIMULATION" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-002/manifest.json", + "report": "tests/golden/WBV2-P13-002/geometry-nodes-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "positive": [ + "allowlisted node graph", + "physics manifest", + "stable hash" + ], + "negative": [ + "unsupported node", + "budget exceeded", + "stale revision" + ], + "recovery": [ + "save/reopen", + "cache disposal" + ], + "commands": [ + "npm --prefix web run test:geometry-node-main-reader", + "npm --prefix web run test:physics-main-reader" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1101-002", + "phase": "1101", + "title": "verify_asset_io_module", + "kind": "module", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1101-001" + ], + "parityId": "ASSET_IO", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-asset_io", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1101-002.md", + "behavior": "Complete the ASSET_IO module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "ASSET_IO", + "sourceBacked": true, + "capabilities": [ + "CAP-ASSET-LINK-OVERRIDE-RELOAD", + "CAP-ASSET-CATALOG-MUTATION" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P11-003/manifest.json", + "report": "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P10-003/manifest.json", + "report": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json" + } + ], + "positive": [ + "append", + "link", + "override", + "reload", + "asset catalog v2" + ], + "negative": [ + "missing source", + "ownership violation", + "hash drift", + "collision" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "IndexedDB restart" + ], + "commands": [ + "npm --prefix web run test:asset-catalog-v2", + "npm --prefix web run test:asset-catalog-migration", + "npm --prefix web run test:asset-catalog-negatives", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-asset-link-override-production.spec.ts tests/e2e/wbv2-asset-catalog-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1101-003", + "phase": "1101", + "title": "verify_sculpt_paint_module", + "kind": "module", + "owner": "SCULPT_PAINT", + "dependsOn": [ + "WBV2-P1101-002" + ], + "parityId": "SCULPT_PAINT", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-sculpt_paint", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1101-003.md", + "behavior": "Complete the SCULPT_PAINT module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SCULPT_PAINT", + "sourceBacked": true, + "capabilities": [ + "CAP-PAINT-ATTRIBUTES", + "CAP-SCULPT-PAINT" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P16-002/manifest.json", + "report": "tests/golden/WBV2-P16-002/paint-attributes-receipt-report.json" + } + ], + "positive": [ + "vertex colors", + "vertex weights", + "bounded sculpt stroke" + ], + "negative": [ + "mirror unverified", + "invalid patch", + "unsupported brush" + ], + "recovery": [ + "undo", + "redo", + "save/reopen" + ], + "commands": [ + "npm --prefix web run test:paint-roundtrip", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-paint-attributes-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1102-000", + "phase": "1102", + "title": "implement_ui_editor_module", + "kind": "module", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1101-003" + ], + "parityId": "UI_EDITOR", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-ui_editor", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1102-000.md", + "behavior": "Complete the UI_EDITOR module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "UI_EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-UI-EDITOR" + ], + "sourcePaths": [ + "web/protocol/editor-workflow.ts", + "web/app/src/app/App.tsx", + "web/app/src/workers/web-engine.worker.ts" + ], + "reuseReceipts": [], + "positive": [ + "editor context", + "workspace", + "area/region" + ], + "negative": [ + "unsupported editor", + "invalid context" + ], + "recovery": [ + "worker restart", + "save/reopen" + ], + "commands": [ + "npm --prefix web run test:editor-main-reader", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/ui-editor-workflow-production.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1102-001", + "phase": "1102", + "title": "close_module_execution_gate", + "kind": "module", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P1102-000" + ], + "parityId": "INVENTORY_GATE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-inventory_gate", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1102-001.md", + "behavior": "Complete the INVENTORY_GATE module through its shared Blender Main primitives and aggregate case matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "INVENTORY_GATE", + "sourceBacked": true, + "capabilities": [], + "sourcePaths": [ + "tests/golden/WBV2-P0-002/parity-map.json", + "tests/golden/WBV2-P1100-000/module-execution-plan.json" + ], + "reuseReceipts": [], + "positive": [ + "aggregate module receipts", + "catalog hash" + ], + "negative": [ + "missing receipt", + "hash drift", + "false completion" + ], + "recovery": [ + "re-run affected module only" + ], + "commands": [ + "node tools/web/check-wbv2-module-execution.mjs", + "npm --prefix web run build" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1103-000", + "phase": "1103", + "title": "aggregate_object_operations_module", + "kind": "module", + "owner": "OBJECT", + "dependsOn": [ + "WBV2-P1102-001" + ], + "parityId": "OBJECT_OPERATIONS", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-object_operations", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1103-000.md", + "behavior": "Aggregate the existing source-backed Object Main operations into one module and revalidate the Chromium operator matrix.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "OBJECT_OPERATIONS", + "sourceBacked": true, + "capabilities": [ + "CAP-OBJECT-DUPLICATE", + "CAP-OBJECT-CREATE", + "CAP-OBJECT-PARENT", + "CAP-OBJECT-COLLECTION", + "CAP-OBJECT-RENAME", + "CAP-OBJECT-DELETE", + "CAP-OBJECT-TRANSFORM" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P17-002/manifest.json", + "report": "tests/golden/WBV2-P17-002/object-duplicate-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P18-002/manifest.json", + "report": "tests/golden/WBV2-P18-002/object-create-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P19-002/manifest.json", + "report": "tests/golden/WBV2-P19-002/object-parent-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P20-002/manifest.json", + "report": "tests/golden/WBV2-P20-002/collection-create-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P21-002/manifest.json", + "report": "tests/golden/WBV2-P21-002/object-rename-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P22-002/manifest.json", + "report": "tests/golden/WBV2-P22-002/object-delete-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P23-002/manifest.json", + "report": "tests/golden/WBV2-P23-002/object-transform-receipt-report.json" + } + ], + "positive": [ + "duplicate", + "create", + "parent", + "collection", + "rename", + "delete", + "transform apply" + ], + "negative": [ + "unknown object", + "invalid parent cycle", + "malformed transform" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic second run" + ], + "commands": [ + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-object-duplicate-production.spec.ts tests/e2e/wbv2-object-create-production.spec.ts tests/e2e/wbv2-object-parent-production.spec.ts tests/e2e/wbv2-collection-create-production.spec.ts tests/e2e/wbv2-object-rename-production.spec.ts tests/e2e/wbv2-object-delete-production.spec.ts tests/e2e/wbv2-object-transform-production.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1104-000", + "phase": "1104", + "title": "verify_compositor_sequencer_module", + "kind": "module", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P1103-000" + ], + "parityId": "COMPOSITOR_SEQUENCER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-compositor_sequencer", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1104-000.md", + "behavior": "Verify the source-backed compositor and sequencer module through golden, unsupported-gate and media recovery cases.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main or compositor mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "COMPOSITOR_SEQUENCER", + "sourceBacked": true, + "capabilities": [ + "CAP-COMPOSITOR-NODE-GRAPH", + "CAP-COMPOSITOR-UNSUPPORTED-GATE", + "CAP-SEQUENCER-MEDIA-RECOVERY" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/compositor.ts", + "web/protocol/sequencer.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P29-003/manifest.json", + "report": "tests/golden/WBV2-P29-003/implementation-report.json" + } + ], + "positive": [ + "compositor node graph", + "sequencer still-image timeline", + "media cache contract" + ], + "negative": [ + "unsupported compositor node", + "invalid sequencer strip", + "stale media revision" + ], + "recovery": [ + "worker restart", + "save/reopen", + "media cache replay", + "movie codec blocked without READY receipt" + ], + "commands": [ + "npm --prefix web run test:compositor-node-golden", + "npm --prefix web run test:compositor-unsupported-gate", + "npm --prefix web run test:sequencer-main-reader", + "node --test web/tests/unit/sequencer-media-cache.test.mjs", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/smoke.spec.ts -g \"N-021 sequencer|real Blender 5.2 sequencer\"", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1105-000", + "phase": "1105", + "title": "verify_audio_particle_module", + "kind": "module", + "owner": "AUDIO_PARTICLE", + "dependsOn": [ + "WBV2-P1104-000" + ], + "parityId": "AUDIO_PARTICLE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-audio_particle", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1105-000.md", + "behavior": "Verify Sound, Speaker and ParticleSettings mutations against authoritative Blender Main with explicit build capability gates.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven or a typed build capability blocker is recorded", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "AUDIO_PARTICLE", + "sourceBacked": true, + "capabilities": [ + "CAP-SOUND-PROPERTIES", + "CAP-SPEAKER-PROPERTIES", + "CAP-PARTICLE-SETTINGS" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/protocol/io-media-commands.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P33-001/manifest.json", + "report": "tests/golden/WBV2-P33-001/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P33-002/manifest.json", + "report": "tests/golden/WBV2-P33-002/implementation-report.json" + } + ], + "positive": [ + "Sound properties", + "Speaker properties", + "ParticleSettings properties" + ], + "negative": [ + "missing Main datablock", + "unsupported build feature", + "out-of-range property" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker restart" + ], + "commands": [ + "cmake --build build_web_blender6 --target web_engine -- -j8", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-audio-particle-production.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1106-000", + "phase": "1106", + "title": "verify_rig_animation_module", + "kind": "module", + "owner": "RIG", + "dependsOn": [ + "WBV2-P1105-000" + ], + "parityId": "RIG_ANIMATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-rig_animation", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1106-000.md", + "behavior": "Verify armature pose, constraints and NLA animation through the existing Blender Main primitives.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "RIG_ANIMATION", + "sourceBacked": true, + "capabilities": [ + "CAP-RIG-POSE", + "CAP-CONSTRAINTS", + "CAP-NLA-ANIMATION" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/web-engine.ts", + "web/protocol/nla.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-003/manifest.json", + "report": "tests/golden/WBV2-P13-003/rig-pose-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "positive": [ + "armature pose", + "constraint edit", + "NLA stack" + ], + "negative": [ + "missing bone", + "invalid constraint influence", + "stale NLA revision" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic second run" + ], + "commands": [ + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-rig-pose-production.spec.ts", + "npm --prefix web run test:nla-operator", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1107-000", + "phase": "1107", + "title": "verify_modifier_system_module", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1106-000" + ], + "parityId": "MODIFIER_SYSTEM", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_system", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1107-000.md", + "behavior": "Verify modifier stack visibility and bounded parameter mutation through authoritative Blender Main.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_SYSTEM", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER-STATE-MUTATION", + "CAP-MODIFIER-PARAMETER-EDIT", + "CAP-MODIFIER-STACK-READER" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/protocol/modifier-graph.ts", + "web/protocol/depsgraph.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P9-002/manifest.json", + "report": "tests/golden/WBV2-P9-002/modifier-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P11-002/manifest.json", + "report": "tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json" + } + ], + "positive": [ + "modifier visibility toggle", + "bounded DECIMATE parameter mutation", + "modifier stack evaluation reader" + ], + "negative": [ + "unknown modifier UUID", + "stale mesh revision", + "out-of-range parameter" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic second run" + ], + "commands": [ + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-production.spec.ts tests/e2e/wbv2-modifier-parameter-production.spec.ts", + "npm --prefix web run test:modifier-goldens", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1108-000", + "phase": "1108", + "title": "verify_nodes_graph_module", + "kind": "module", + "owner": "NODES", + "dependsOn": [ + "WBV2-P1107-000" + ], + "parityId": "NODES_GRAPH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-nodes_graph", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1108-000.md", + "behavior": "Verify Geometry Nodes graph identity, allowlisted evaluation, field budgets and unsupported graph retention.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive graph reader/evaluation evidence is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "NODES_GRAPH", + "sourceBacked": true, + "capabilities": [ + "CAP-GEOMETRY-NODES-GRAPH", + "CAP-GEOMETRY-NODES-ALLOWLIST", + "CAP-GEOMETRY-NODES-FIELD-BUDGET" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/protocol/geometry-nodes.ts", + "web/protocol/geometry-node-commands.ts", + "web/protocol/depsgraph.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-002/manifest.json", + "report": "tests/golden/WBV2-P13-002/geometry-nodes-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "positive": [ + "allowlisted graph identity", + "Blender depsgraph geometry evaluation", + "field materialization with exact domain cardinality" + ], + "negative": [ + "unsupported node graph", + "field budget overflow", + "stale or invalid graph command" + ], + "recovery": [ + "save/reopen", + "worker restart", + "graph retention after rejected command", + "deterministic second run" + ], + "commands": [ + "npm --prefix web run test:geometry-node-evaluator-golden", + "npm --prefix web run test:geometry-node-field-budget", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-geometry-nodes-production.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1109-000", + "phase": "1109", + "title": "verify_io_format_module", + "kind": "module", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P1108-000" + ], + "parityId": "IO_FORMAT", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-io_format", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1109-000.md", + "behavior": "Verify format capability routing, runtime receipts, recovery and fail-closed file UI gates.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive format routing/readiness evidence is proven", + "negative and recovery cases are proven", + "Chromium and deterministic recovery receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "IO_FORMAT", + "sourceBacked": true, + "capabilities": [ + "CAP-IO-FORMAT-CAPABILITY-MATRIX", + "CAP-IO-FORMAT-RUNTIME-RECEIPTS", + "CAP-IO-FORMAT-RECOVERY", + "CAP-IO-FORMAT-UI-GATE" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/asset-library-io.ts", + "web/protocol/io-format-capability-matrix.ts", + "web/protocol/io-format-receipt-binding.ts", + "web/protocol/io-format-runtime-receipt.ts", + "web/protocol/io-format-recovery.ts", + "web/protocol/io-format-ui-gate.ts", + "web/protocol/glb-export.ts", + "web/protocol/glb-import.ts", + "web/protocol/nonmesh-export.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [], + "positive": [ + "GLB export readiness", + "format runtime receipt inventory", + "declared .blend import route" + ], + "negative": [ + "unverified format route", + "cancelled or OOM operation", + "unsupported file extension" + ], + "recovery": [ + "worker restart", + "small operation recovery", + "deterministic receipt replay", + "fail-closed UI route" + ], + "commands": [ + "node tools/web/check-io-format-receipt-bindings.mjs", + "node tools/web/check-io-format-runtime-receipts.mjs", + "node tools/web/check-io-format-recovery.mjs", + "node tools/web/check-io-format-ui-gate.mjs", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/io-format-recovery.spec.ts tests/e2e/io-format-ui-gate.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1110-000", + "phase": "1110", + "title": "verify_render_pipeline_module", + "kind": "module", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P1109-000" + ], + "parityId": "RENDER_PIPELINE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-render_pipeline", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1110-000.md", + "behavior": "Verify render backend routing, explicit resource budgets and Blender reference comparison in Chromium.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive render/reference evidence is proven", + "negative and recovery cases are proven", + "Chromium and deterministic render receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "RENDER_PIPELINE", + "sourceBacked": true, + "capabilities": [ + "CAP-RENDER-BACKEND-ROUTING", + "CAP-RENDER-RESOURCE-BUDGET", + "CAP-RENDER-REFERENCE-COMPARISON" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/render-routing.ts", + "web/protocol/render-budget.ts", + "web/protocol/render-capabilities.ts", + "web/protocol/render-image-comparison.ts", + "web/protocol/server-render-job.ts", + "web/app/src/three-adapter/render-routing.ts", + "web/app/src/three-adapter/render-image-comparison.ts", + "web/app/src/workers/viewport-render.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [], + "positive": [ + "bounded local backend routing", + "reference render metrics", + "resource budget acceptance" + ], + "negative": [ + "unknown or unavailable backend", + "aggregate texture/light budget overflow", + "wrong composition reference" + ], + "recovery": [ + "retain previous texture set", + "offscreen renderer parity", + "worker restart", + "deterministic second render" + ], + "commands": [ + "npm --prefix web run test:render-resource-budget", + "npm --prefix web run test:render-routing", + "npm --prefix web run test:render-reference", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1111-000", + "phase": "1111", + "title": "verify_scripting_security_module", + "kind": "module", + "owner": "SCRIPTING", + "dependsOn": [ + "WBV2-P1110-000" + ], + "parityId": "SCRIPTING_SECURITY", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-scripting_security", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1111-000.md", + "behavior": "Verify script source Main reader, deny-by-default permission policy and sandbox isolation/recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive reader and policy evidence is proven", + "negative and recovery cases are proven", + "Chromium sandbox receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SCRIPTING_SECURITY", + "sourceBacked": true, + "capabilities": [ + "CAP-SCRIPT-MAIN-READER", + "CAP-SCRIPT-PERMISSION-POLICY", + "CAP-SCRIPT-SANDBOX-ISOLATION", + "CAP-SCRIPT-SANDBOX-RECOVERY" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/scene-ir.ts", + "web/protocol/scripting-platform.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/workers/script-permission-policy-test.worker.ts", + "web/app/src/workers/script-sandbox-isolation-test.worker.ts", + "web/app/src/workers/script-sandbox-recovery-test.worker.ts", + "web/app/src/testing/script-sandbox-recovery.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [], + "positive": [ + "script source inventory reader", + "explicit READ_MAIN permission", + "new-generation recovery audit" + ], + "negative": [ + "autorun denied by default", + "undeclared permission", + "sandbox crash/timeout/late result" + ], + "recovery": [ + "worker restart", + "sandbox generation rollover", + "continuous audit chain", + "deterministic second run" + ], + "commands": [ + "npm --prefix web run test:script-main-reader", + "npm --prefix web run test:scripting-isolation", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/script-permission-policy.spec.ts tests/e2e/script-sandbox-isolation.spec.ts tests/e2e/script-sandbox-recovery.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1112-000", + "phase": "1112", + "title": "verify_animation_timeline_module", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1111-000" + ], + "parityId": "ANIMATION_TIMELINE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-animation_timeline", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1112-000.md", + "behavior": "Verify frame evaluation and NLA time mapping through the production Worker and Blender Main.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive frame/NLA evaluation is proven", + "negative and recovery cases are proven", + "Chromium and deterministic evaluation receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "ANIMATION_TIMELINE", + "sourceBacked": true, + "capabilities": [ + "CAP-FRAME-EVALUATION", + "CAP-NLA-TIME-MAPPING", + "CAP-ANIMATION-SAVE-REOPEN" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/protocol/nla.ts", + "web/protocol/depsgraph.ts", + "web/protocol/scene-ir.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "positive": [ + "frame 1/5/10 evaluation", + "NLA track and strip mapping", + "Blender depsgraph animation result" + ], + "negative": [ + "stale NLA revision", + "invalid strip topology", + "unsupported animation domain" + ], + "recovery": [ + "save/reopen", + "worker restart", + "deterministic repeated evaluation", + "preserve rejected stack" + ], + "commands": [ + "npm --prefix web run test:frame-evaluation", + "node tools/web/check-nla-evaluation-golden.mjs", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/nla-evaluation-golden.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1113-000", + "phase": "1113", + "title": "verify_shader_material_module", + "kind": "module", + "owner": "MATERIAL", + "dependsOn": [ + "WBV2-P1112-000" + ], + "parityId": "SHADER_MATERIAL", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-shader_material", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1113-000.md", + "behavior": "Verify bounded Shader graph compilation, stable compile keys and fail-closed pipeline recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Shader Main compilation is proven", + "negative and recovery cases are proven", + "Chromium and deterministic compile receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SHADER_MATERIAL", + "sourceBacked": true, + "capabilities": [ + "CAP-SHADER-GRAPH-COMPILER", + "CAP-SHADER-COMPILE-KEY", + "CAP-SHADER-FAIL-CLOSED-RECOVERY" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/protocol/shader-graph.ts", + "web/protocol/shader-graph-commands.ts", + "web/protocol/shader-compiler.ts", + "web/protocol/render-capabilities.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [], + "positive": [ + "Principled/Image/Normal/Math graph compile", + "stable compile key", + "real Main shader material path" + ], + "negative": [ + "unknown shader node", + "graph cycle or duplicate link", + "unsupported renderer backend" + ], + "recovery": [ + "retain previous material after compile failure", + "worker restart", + "deterministic repeated compile", + "save/reopen material graph" + ], + "commands": [ + "npm --prefix web run test:shader-compile", + "npm --prefix web run test:shader-pipeline", + "npm --prefix web run test:shader-capability", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1114-000", + "phase": "1114", + "title": "verify_grease_pencil_module", + "kind": "module", + "owner": "DRAWING", + "dependsOn": [ + "WBV2-P1113-000" + ], + "parityId": "GREASE_PENCIL", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-grease_pencil", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1114-000.md", + "behavior": "Verify Grease Pencil layer/frame Main mutations, stable identity validation and roundtrip recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Grease Pencil Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "GREASE_PENCIL", + "sourceBacked": true, + "capabilities": [ + "CAP-GREASE-PENCIL-LAYER-FRAME", + "CAP-GREASE-PENCIL-STROKE-READER", + "CAP-GREASE-PENCIL-ROUNDTRIP" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/protocol/grease-pencil.ts", + "web/protocol/grease-pencil-reorder.ts", + "web/protocol/grease-pencil-selection.ts", + "web/protocol/grease-pencil-marquee.ts", + "web/app/src/app/App.tsx", + "web/app/src/three-adapter/grease-pencil.ts", + "web/app/src/three-adapter/viewport.ts", + "web/app/src/three-adapter/offscreen-viewport.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [], + "positive": [ + "create and reorder layer", + "insert and move frame", + "stable Grease Pencil drawing reader" + ], + "negative": [ + "forged drawing identity", + "occupied frame target", + "stale layer/frame revision" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic layer/frame replay" + ], + "commands": [ + "npm --prefix web run test:grease-pencil-reorder", + "npm --prefix web run test:grease-pencil", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1115-000", + "phase": "1115", + "title": "verify_curve_surface_editing_module", + "kind": "module", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P1114-000" + ], + "parityId": "CURVE_SURFACE_EDITING", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-curve_surface_editing", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1115-000.md", + "behavior": "Verify Curve topology/handle edits, Surface topology and non-mesh/font roundtrip through Blender Main.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive non-mesh Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "CURVE_SURFACE_EDITING", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-TOPOLOGY-HANDLES", + "CAP-SURFACE-TOPOLOGY", + "CAP-NONMESH-FONT-ROUNDTRIP" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/web-engine.ts", + "web/protocol/nonmesh-geometry-commands.ts", + "web/protocol/curve-topology-editor.ts", + "web/protocol/non-mesh.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P12-004/manifest.json", + "report": "tests/golden/WBV2-P12-004/viewport-nonmesh-receipt-report.json" + } + ], + "positive": [ + "Curve control point and handle edit", + "Curve cyclic/topology operator", + "Surface and Font property mutation" + ], + "negative": [ + "invalid curve selection/domain", + "occupied or stale frame/topology target", + "malformed non-mesh property" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic multispline replay" + ], + "commands": [ + "npm --prefix web run test:curve-topology-operator", + "npm --prefix web run test:nonmesh-roundtrip", + "npm --prefix web run test:nonmesh-desktop-golden", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1116-000", + "phase": "1116", + "title": "verify_storage_recovery_module", + "kind": "module", + "owner": "STORAGE", + "dependsOn": [ + "WBV2-P1115-000" + ], + "parityId": "STORAGE_RECOVERY", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-storage_recovery", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1116-000.md", + "behavior": "Verify IndexedDB catalog migration/restart and OPFS asset preview deduplication, quarantine and reference GC.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive storage commit/recovery evidence is proven", + "negative and quarantine cases are proven", + "Chromium restart receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "STORAGE_RECOVERY", + "sourceBacked": true, + "capabilities": [ + "CAP-INDEXEDDB-CATALOG-MIGRATION", + "CAP-OPFS-PREVIEW-COMMIT", + "CAP-OPFS-QUARANTINE-GC" + ], + "sourcePaths": [ + "web/protocol/storage.ts", + "web/protocol/storage-budget.ts", + "web/protocol/save-transaction.ts", + "web/protocol/recent-projects.ts", + "web/protocol/asset-preview.ts", + "web/protocol/asset-preview-decode.ts", + "web/app/src/storage/asset-catalog-indexeddb.ts", + "web/app/src/storage/asset-preview-opfs-commit.ts", + "web/app/src/storage/asset-preview-quarantine.ts", + "web/app/src/storage/asset-preview-reference-gc.ts", + "web/app/src/storage/opfs-files.ts", + "web/app/src/storage/migrations.ts", + "web/app/src/workers/storage.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [], + "positive": [ + "v1 to v2 catalog migration", + "page/Worker restart identity", + "content-addressed preview deduplication" + ], + "negative": [ + "partial catalog migration", + "corrupt preview quarantine", + "cross-project or non-final reference GC" + ], + "recovery": [ + "IndexedDB restart", + "OPFS commit replay", + "quarantine cleanup", + "deterministic reference reclamation" + ], + "commands": [ + "npm --prefix web run test:asset-catalog-restart", + "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 typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1117-000", + "phase": "1117", + "title": "verify_simulation_cache_module", + "kind": "module", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P1116-000" + ], + "parityId": "SIMULATION_CACHE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-simulation_cache", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1117-000.md", + "behavior": "Verify simulation cache identity, physics-family payload integrity, lifecycle recovery and deterministic LRU pruning.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive cache identity/lifecycle evidence is proven", + "negative integrity and budget cases are proven", + "Chromium restart and quarantine receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SIMULATION_CACHE", + "sourceBacked": true, + "capabilities": [ + "CAP-SIMULATION-CACHE-IDENTITY", + "CAP-PHYSICS-CACHE-INTEGRITY", + "CAP-SIMULATION-CACHE-RECOVERY" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/simulation-cache.ts", + "web/protocol/physics-simulation.ts", + "web/protocol/physics-cache-playback.ts", + "web/protocol/storage.ts", + "web/app/src/workers/storage.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P13-004/manifest.json", + "report": "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" + } + ], + "positive": [ + "graph/source/revision cache identity", + "all physics-family frame hashes", + "verified playback lifecycle" + ], + "negative": [ + "source or payload hash drift", + "revision/range mismatch", + "cache byte/frame budget overflow" + ], + "recovery": [ + "cancel and cleanup", + "LRU prune with protected playback", + "corruption quarantine", + "worker restart" + ], + "commands": [ + "npm --prefix web run test:simulation-cache-identity", + "npm --prefix web run test:simulation-cache-lifecycle", + "npm --prefix web run test:physics-cache-family", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1118-000", + "phase": "1118", + "title": "verify_ui_input_interaction_module", + "kind": "module", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1117-000" + ], + "parityId": "UI_INPUT_INTERACTION", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-ui_input_interaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1118-000.md", + "behavior": "Verify keyboard-only user actions, input mutex, IME/pointer state and responsive editor interaction under deployment CSP.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive keyboard Main mutation and save are proven", + "negative mutex/input cases are proven", + "Chromium accessibility and responsive receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "UI_INPUT_INTERACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-KEYBOARD-USER-ACTIONS", + "CAP-INPUT-MODAL-STATE", + "CAP-IME-SHORTCUT-GUARD", + "CAP-RESPONSIVE-CSP-UI" + ], + "sourcePaths": [ + "web/app/index.html", + "web/app/src/app/App.tsx", + "web/app/src/app/app-shell.css", + "web/app/src/workers/web-engine.worker.ts", + "web/protocol/user-action-state.ts", + "web/protocol/project-action-mutex.ts", + "web/protocol/ime-composition.ts", + "web/protocol/input-modal.ts", + "web/protocol/pointer-contract.ts", + "web/protocol/worker-fault.ts", + "web/tests/unit/user-action-state.test.mjs", + "web/tests/unit/project-action-mutex.test.mjs", + "web/tests/unit/ime-composition.test.mjs", + "web/tests/unit/input-modal.test.mjs", + "web/tests/unit/pointer-contract.test.mjs" + ], + "reuseReceipts": [], + "positive": [ + "keyboard-only Add Cube Main mutation", + "keyboard save/reopen and GLB export", + "responsive controls at desktop/mobile viewports" + ], + "negative": [ + "concurrent project action mutex", + "IME shortcut suppression", + "pointer cancel/touch modal cleanup" + ], + "recovery": [ + "worker restart", + "save interruption recovery", + "responsive layout preservation", + "deterministic repeated keyboard loop" + ], + "commands": [ + "node --test web/tests/unit/user-action-state.test.mjs web/tests/unit/project-action-mutex.test.mjs web/tests/unit/ime-composition.test.mjs web/tests/unit/input-modal.test.mjs web/tests/unit/pointer-contract.test.mjs", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/user-action-state.spec.ts tests/e2e/project-action-mutex.spec.ts tests/e2e/keyboard-accessibility.spec.ts tests/e2e/responsive-layout.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1119-000", + "phase": "1119", + "title": "verify_library_workflow_module", + "kind": "module", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1118-000" + ], + "parityId": "LIBRARY_WORKFLOW", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-library_workflow", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1119-000.md", + "behavior": "Verify append, link, override and reload library flows through authoritative Main with path and dependency safety gates.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive library Main mutation is proven", + "negative and recovery cases are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "LIBRARY_WORKFLOW", + "sourceBacked": true, + "capabilities": [ + "CAP-LIBRARY-APPEND", + "CAP-LIBRARY-LINK", + "CAP-LIBRARY-OVERRIDE", + "CAP-LIBRARY-RELOAD-SAFETY" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/library-main-append.ts", + "web/protocol/library-linked-mutation.ts", + "web/protocol/library-linked-reload.ts", + "web/protocol/library-linked-missing.ts", + "web/protocol/library-override-writer.ts", + "web/protocol/library-override-freshness.ts", + "web/protocol/library-negative-cases.ts", + "web/protocol/library-operation-identity.ts", + "web/protocol/library-source-origin.ts", + "web/protocol/asset-path.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P11-003/manifest.json", + "report": "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json" + }, + { + "manifest": "tests/golden/WBV2-P9-003/manifest.json", + "report": "tests/golden/WBV2-P9-003/asset-catalog-receipt-report.json" + } + ], + "positive": [ + "append object into Main", + "linked read-only object", + "local override and reload identity" + ], + "negative": [ + "missing library source", + "dependency/cross-library cycle", + "unsafe path or ownership mutation" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic library replay" + ], + "commands": [ + "npm --prefix web run test:library-main-append", + "npm --prefix web run test:library-link-chromium", + "npm --prefix web run test:library-override-chromium", + "npm --prefix web run test:library-negative-cases", + "npm --prefix web run test:library-path-security", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1120-000", + "phase": "1120", + "title": "verify_volume_nanovdb_module", + "kind": "module", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P1119-000" + ], + "parityId": "VOLUME_NANOVDB", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-volume_nanovdb", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1120-000.md", + "behavior": "Verify NanoVDB manifest, paged feedback, OPFS commit/restart and production viewport volume roundtrip.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive volume resource and viewport evidence is proven", + "negative and recovery cases are proven", + "Chromium OPFS/restart receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "VOLUME_NANOVDB", + "sourceBacked": true, + "capabilities": [ + "CAP-NANOVDB-MANIFEST", + "CAP-NANOVDB-PAGED-FEEDBACK", + "CAP-NANOVDB-OPFS-RESTART", + "CAP-NANOVDB-VIEWPORT-ROUNDTRIP" + ], + "sourcePaths": [ + "web/protocol/volume-vdb.ts", + "web/protocol/nanovdb-page-feedback.ts", + "web/protocol/nanovdb-device-recovery.ts", + "web/protocol/storage.ts", + "web/app/src/volume/nanovdb-opfs.ts", + "web/app/src/volume/nanovdb-stream.ts", + "web/app/src/volume/nanovdb-viewport.ts", + "web/app/src/volume/nanovdb-float32.ts", + "web/app/src/render/nanovdb-volume-renderer.ts", + "web/app/src/workers/vdb-opfs-test.worker.ts", + "web/app/src/workers/storage.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [], + "positive": [ + "validated NanoVDB bundle manifest", + "content-addressed OPFS commit", + "main/offscreen production viewport volume" + ], + "negative": [ + "manifest/chunk hash mismatch", + "stale source binding", + "WebGPU/resource availability block" + ], + "recovery": [ + "OPFS Worker restart", + "paged feedback resume", + "quota/device loss cleanup", + "deterministic volume save/reopen" + ], + "commands": [ + "npm --prefix web run test:vdb-availability", + "npm --prefix web run test:vdb-native", + "npm --prefix web run test:nanovdb-page-feedback", + "npm --prefix web run test:nanovdb-opfs-restart", + "npm --prefix web run test:nanovdb-volume-roundtrip", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1121-000", + "phase": "1121", + "title": "verify_paint_stroke_module", + "kind": "module", + "owner": "SCULPT", + "dependsOn": [ + "WBV2-P1120-000" + ], + "parityId": "PAINT_STROKE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-paint_stroke", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1121-000.md", + "behavior": "Verify paint pointer sessions, depth visibility and PBVH capability gates through the production Worker.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive paint Main transaction is proven", + "negative and recovery cases are proven", + "Chromium pointer/GPU receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "PAINT_STROKE", + "sourceBacked": true, + "capabilities": [ + "CAP-PAINT-POINTER-SESSION", + "CAP-PAINT-DEPTH-VISIBILITY", + "CAP-PAINT-PBVH-GATE" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/web-engine.ts", + "web/protocol/sculpt.ts", + "web/protocol/paint.ts", + "web/protocol/paint-stroke-session.ts", + "web/protocol/paint-depth-visibility.ts", + "web/protocol/paint-pbvh-capability.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/three-adapter/paint-depth-visibility.ts", + "web/app/src/three-adapter/viewport.ts", + "web/app/src/three-adapter/offscreen-viewport.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [], + "positive": [ + "ordered paint pointer chunks", + "main/offscreen depth visibility", + "PBVH inventory capability query" + ], + "negative": [ + "stale/discontinuous pointer chunks", + "forged or over-budget depth samples", + "missing PBVH WASM entrypoint" + ], + "recovery": [ + "pointer cancel without Main mutation", + "undo step after paint commit", + "worker restart", + "deterministic capability replay" + ], + "commands": [ + "npm --prefix web run test:paint-stroke-session", + "npm --prefix web run test:paint-depth-visibility", + "npm --prefix web run test:paint-pbvh-capability", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1122-000", + "phase": "1122", + "title": "verify_engine_runtime_module", + "kind": "module", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P1121-000" + ], + "parityId": "ENGINE_RUNTIME", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-engine_runtime", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1122-000.md", + "behavior": "Verify WebEngine variant manifest/selection, compiled WASM Main ABI and Worker crash recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive compiled WASM Main lifecycle is proven", + "negative variant/hash cases are proven", + "Chromium Worker restart receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "ENGINE_RUNTIME", + "sourceBacked": true, + "capabilities": [ + "CAP-ENGINE-VARIANT-MANIFEST", + "CAP-ENGINE-WASM-MAIN-ABI", + "CAP-WORKER-CRASH-RECOVERY" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_api.h", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/CMakeLists.txt", + "web/protocol/engine-variant.ts", + "web/protocol/worker-fault.ts", + "web/protocol/save-transaction.ts", + "web/app/src/engine-client/engine-variant-bootstrap.ts", + "web/app/src/engine-client/browser-engine-variant-session.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/workers/storage.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [], + "positive": [ + "single/pthread manifest binding", + "compiled WASM Main open/save lifecycle", + "engine and storage Worker recovery" + ], + "negative": [ + "malformed variant/resource declaration", + "mixed-version/hash mismatch", + "pthread unavailable fallback" + ], + "recovery": [ + "single-thread fallback", + "Worker crash restart", + "operation-log restore", + "deterministic repeated startup" + ], + "commands": [ + "npm --prefix web run test:engine-manifest-v2", + "npm --prefix web run test:engine-variant-selection", + "npm --prefix web run test:engine-variant-fallback", + "npm --prefix web run test:engine-variant-install", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-native-engine-production.spec.ts tests/e2e/worker-crash-recovery.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1123-000", + "phase": "1123", + "title": "repair_glb_roundtrip_dependency_module", + "kind": "module", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P1122-000" + ], + "parityId": "GLB_ROUNDTRIP_REPAIR", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-glb_roundtrip_repair", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1123-000.md", + "behavior": "Repair the standalone GLB checker dependency chain and verify mesh/non-mesh Blender roundtrip plus Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive GLB and non-mesh roundtrip are proven", + "negative and recovery cases are proven", + "Chromium save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "GLB_ROUNDTRIP_REPAIR", + "sourceBacked": true, + "capabilities": [ + "CAP-GLB-MESH-ROUNDTRIP", + "CAP-GLB-NONMESH-ROUNDTRIP", + "CAP-GLB-CHROMIUM-RECOVERY" + ], + "sourcePaths": [ + "tools/web/check-glb-blender-roundtrip.mjs", + "tools/web/check-nonmesh-glb-blender-roundtrip.mjs", + "tools/web/blender-check-glb-roundtrip.py", + "web/protocol/glb-export.ts", + "web/protocol/glb-import.ts", + "web/protocol/nonmesh-export.ts", + "web/protocol/nonmesh-binary.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx" + ], + "reuseReceipts": [], + "positive": [ + "mesh/material/skin/animation GLB roundtrip", + "Curve/Surface/Font/Metaball non-mesh mapping", + "desktop GLB Main persistence in Chromium" + ], + "negative": [ + "sparse or oversized GLB", + "external URI/extension rejection", + "non-mesh export loss gate" + ], + "recovery": [ + "cancel without publishing output", + "Worker restart", + "OPFS quota retains old asset", + "deterministic Blender roundtrip" + ], + "commands": [ + "npm --prefix web run test:glb-blender-roundtrip", + "npm --prefix web run test:nonmesh-glb-blender-roundtrip", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/glb-negative-cases.spec.ts tests/e2e/glb-recovery.spec.ts tests/e2e/glb-main-persistence.spec.ts", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1124-000", + "phase": "1124", + "title": "record_historical_hash_drift_module", + "kind": "module", + "owner": "PROVENANCE", + "dependsOn": [ + "WBV2-P1123-000" + ], + "parityId": "HISTORICAL_HASH_DRIFT", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-historical_hash_drift", + "gate": "EVIDENCE", + "card": "docs/tasks/WBV2-P1124-000.md", + "behavior": "Record legacy M12 artifact hash drift without re-signing historical manifests or changing the immutable inventory.", + "outputs": [ + "drift report", + "module receipt", + "manifest", + "status" + ], + "acceptance": [ + "original and observed hashes are recorded", + "provenance remains BLOCKED_SOURCE_LOST where bytes cannot be restored", + "historical manifests and inventory remain unchanged", + "deterministic drift evidence is reproducible", + "no full-family parity claim" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "HISTORICAL_HASH_DRIFT", + "sourceBacked": true, + "capabilities": [ + "CAP-HISTORICAL-HASH-AUDIT", + "CAP-PROVENANCE-SOURCE-LOST-GATE" + ], + "sourcePaths": [ + "tools/web/check-m12-manifest-drift.mjs", + "tests/golden/corrective/rehydration/M12-manifest-sha-drift.json", + "tests/golden/WBV2-P0-002/parity-map.json" + ], + "reuseReceipts": [], + "positive": [ + "84 drift entries captured", + "43 affected artifact paths indexed", + "immutable inventory binding preserved" + ], + "negative": [ + "missing original bytes", + "attempted historical re-signing", + "inventory mutation" + ], + "recovery": [ + "deterministic report rerun", + "source cache can restore original bytes later", + "new capability manifests reference drift evidence only" + ], + "commands": [ + "node tools/web/check-m12-manifest-drift.mjs --write", + "node tools/web/check-m12-manifest-drift.mjs", + "node tools/web/check-wbv2-module-execution.mjs" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1125-000", + "phase": "1125", + "title": "repair_geometry_nodes_allowlist_module", + "kind": "module", + "owner": "NODES", + "dependsOn": [ + "WBV2-P1124-000" + ], + "parityId": "GEOMETRY_NODES_ALLOWLIST_REPAIR", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-geometry_nodes_allowlist_repair", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1125-000.md", + "behavior": "Persist Geometry Nodes graph overrides in Web-safe Main storage and align allowlist assertions with real materialization behavior.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "supported graph Main materialization is proven", + "unsupported graph remains rejected without mutation", + "save/reopen graph retention is exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "GEOMETRY_NODES_ALLOWLIST_REPAIR", + "sourceBacked": true, + "capabilities": [ + "CAP-GEOMETRY-NODES-MAIN-PERSISTENCE", + "CAP-GEOMETRY-NODES-ALLOWLIST-CONSISTENCY", + "CAP-GEOMETRY-NODES-SAVE-REOPEN" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/geometry-nodes.ts", + "web/protocol/geometry-node-commands.ts", + "web/protocol/web-engine.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/geometry-node-allowlist.spec.ts", + "web/tests/e2e/wbv2-geometry-nodes-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [], + "positive": [ + "allowlisted graph materializes into Main", + "Scene IDProperty graph override persists", + "save/reopen retains graph identity/hash" + ], + "negative": [ + "unsupported simulation node", + "invalid graph schema", + "missing node/link endpoint" + ], + "recovery": [ + "rejected graph leaves baseline unchanged", + "undo/redo graph override", + "save/reopen", + "deterministic second run" + ], + "commands": [ + "cmake --build build_web_blender6 --target web_engine -- -j8", + "npm --prefix web run test:geometry-node-allowlist", + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-geometry-nodes-production.spec.ts", + "npm --prefix web run test:geometry-node-field-budget", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1126-000", + "phase": "1126", + "title": "verify_grease_pencil_viewport_module", + "kind": "module", + "owner": "DRAWING", + "dependsOn": [ + "WBV2-P1125-000" + ], + "parityId": "GREASE_PENCIL_VIEWPORT", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-grease_pencil_viewport", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1126-000.md", + "behavior": "Verify Grease Pencil 2D/3D selection and marquee integration on both viewport backends using an isolated Chromium port.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "2D and 3D selection revisions converge", + "main-thread and Offscreen marquee are exact", + "stale/foreign selection cases remain fail-closed", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "GREASE_PENCIL_VIEWPORT", + "sourceBacked": true, + "capabilities": [ + "CAP-GREASE-PENCIL-SELECTION-REVISION", + "CAP-GREASE-PENCIL-MARQUEE-MAIN", + "CAP-GREASE-PENCIL-MARQUEE-OFFSCREEN" + ], + "sourcePaths": [ + "web/protocol/grease-pencil-selection.ts", + "web/protocol/grease-pencil-marquee.ts", + "web/app/src/app/App.tsx", + "web/app/src/three-adapter/grease-pencil.ts", + "web/app/src/three-adapter/viewport.ts", + "web/app/src/three-adapter/offscreen-viewport.ts", + "web/app/src/workers/viewport-render.worker.ts" + ], + "reuseReceipts": [], + "positive": [ + "2D canvas selection revision", + "main-thread 3D marquee selection", + "OffscreenCanvas 3D marquee selection" + ], + "negative": [ + "stale selection revision", + "foreign drawing identity", + "duplicate or forged point candidate" + ], + "recovery": [ + "selection convergence across backends", + "worker viewport restart", + "deterministic repeated marquee", + "preserve Main revision" + ], + "commands": [ + "WEB_TEST_PORT=5331 npm --prefix web run test:e2e -- --workers=1 tests/e2e/grease-pencil-selection.spec.ts tests/e2e/grease-pencil-marquee.spec.ts", + "node --test web/tests/unit/grease-pencil-selection.test.mjs web/tests/unit/grease-pencil-marquee.test.mjs", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1127-000", + "phase": "1127", + "title": "verify_tracking_mask_module", + "kind": "module", + "owner": "TRACKING", + "dependsOn": [ + "WBV2-P1126-000" + ], + "parityId": "TRACKING_MASK", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-tracking_mask", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1127-000.md", + "behavior": "Verify Mask reader, editable point raycast/marquee and tracking capability gates through Chromium.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Mask reader and interaction evidence is proven", + "negative solve/resource cases are proven", + "Chromium stable IDs and recovery receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "TRACKING_MASK", + "sourceBacked": true, + "capabilities": [ + "CAP-MASK-MAIN-READER", + "CAP-MASK-POINT-RAYCAST", + "CAP-TRACKING-SOLVE-GATE" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/tracking-mask.ts", + "web/protocol/scene-ir.ts", + "web/app/src/tracking/MaskSelection.ts", + "web/app/src/app/App.tsx", + "web/app/src/three-adapter/viewport.ts", + "web/app/src/three-adapter/offscreen-viewport.ts", + "web/tests/e2e/smoke.spec.ts" + ], + "reuseReceipts": [], + "positive": [ + "Mask layers and splines reader", + "editable Mask point raycast", + "N-022 tracking marker/mask gate" + ], + "negative": [ + "foreign mask point identity", + "missing resource binding", + "camera solve unavailable" + ], + "recovery": [ + "main/offscreen marquee parity", + "worker restart", + "deterministic stable IDs", + "preserve source Main on blocked solve" + ], + "commands": [ + "npm --prefix web run test:mask-main-reader", + "WEB_TEST_PORT=5340 npm --prefix web run test:e2e -- --workers=1 tests/e2e/smoke.spec.ts -g \"N-022 tracking|real Blender 5.2 Mask\"", + "npm --prefix web run typecheck" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1128-000", + "phase": "1128", + "title": "verify_ffmpeg_movie_codec_module", + "kind": "module", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P1127-000" + ], + "parityId": "SEQUENCER_MOVIE_CODEC", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "module-sequencer_movie_codec", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1128-000.md", + "behavior": "Use a local ffmpeg.wasm Worker fallback for movie probing and proxy-frame extraction when Chromium HTML media decoding is unavailable.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and core-resource hashes are bound", + "positive MP4 probe and RGBA frame are proven", + "corrupt and source-identity cases are rejected", + "AbortSignal cancellation leaves no live Worker", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SEQUENCER_MOVIE_CODEC", + "sourceBacked": true, + "capabilities": [ + "CAP-FFMPEG-WASM-MOVIE-PROBE", + "CAP-FFMPEG-WASM-PROXY-FRAME", + "CAP-MOVIE-CODEC-RECOVERY" + ], + "sourcePaths": [ + "web/package.json", + "web/package-lock.json", + "web/protocol/sequencer.ts", + "web/app/src/sequencer/SequencerCodecProbe.ts", + "web/app/src/sequencer/FFmpegMovieProbe.ts", + "web/app/src/sequencer/ffmpeg-movie-probe.worker.ts", + "web/app/src/sequencer/SequencerMediaProxyCache.ts", + "web/app/src/vendor/ffmpeg/ffmpeg-core.js", + "web/app/src/vendor/ffmpeg/ffmpeg-core.wasm", + "web/app/public/vendor/ffmpeg/ffmpeg-core.js", + "web/app/public/vendor/ffmpeg/ffmpeg-core.wasm", + "third_party/ffmpeg.wasm/package.json", + "third_party/ffmpeg.wasm/README.md", + "web/tests/e2e/ffmpeg-movie-probe-production.spec.ts" + ], + "reuseReceipts": [], + "positive": [ + "browser decode fallback to ffmpeg.wasm", + "16x16 MP4 metadata probe", + "8x8 RGBA proxy frame extraction" + ], + "negative": [ + "corrupt movie payload", + "source SHA mismatch", + "ffmpeg runtime unavailable" + ], + "recovery": [ + "AbortSignal cancellation", + "Worker termination after response", + "cache manifest identity binding", + "deterministic repeated probe" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5342 npm --prefix web run test:e2e -- --workers=1 tests/e2e/ffmpeg-movie-probe-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1129-000", + "phase": "1129", + "title": "authorize_scene_settings_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1128-000" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1129", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1129-000.md", + "behavior": "Authorize one source-backed Core Scene Graph settings module after the terminal P1128 module epoch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1128 evidence remains hash-bound", + "existing receipts are reused", + "inventory remains immutable", + "one source-backed module is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ] + }, + { + "id": "WBV2-P1129-001", + "phase": "1129", + "title": "verify_scene_settings_module", + "kind": "module", + "owner": "CORE_SCENE", + "dependsOn": [ + "WBV2-P1129-000" + ], + "parityId": "CORE_SCENE_GRAPH_SETTINGS", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-core_scene_graph_settings", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1129-001.md", + "behavior": "Verify the existing Blender Main scene compositor, performance and sampling setting transactions as one aggregate module.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutations are proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen receipts are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "CORE_SCENE_GRAPH_SETTINGS", + "sourceBacked": true, + "capabilities": [ + "CAP-SCENE-COMPOSITOR-SETTINGS", + "CAP-SCENE-PERFORMANCE-SETTINGS", + "CAP-SCENE-SAMPLING-SETTINGS" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/wbv2-scene-settings-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P65-002/manifest.json", + "report": "tests/golden/WBV2-P65-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P66-002/manifest.json", + "report": "tests/golden/WBV2-P66-002/implementation-report.json" + }, + { + "manifest": "tests/golden/WBV2-P67-002/manifest.json", + "report": "tests/golden/WBV2-P67-002/implementation-report.json" + } + ], + "positive": [ + "compositor device/precision mutation", + "performance thread/persistence mutation", + "sampling filter/dither mutation" + ], + "negative": [ + "invalid sampling range", + "unknown scene target", + "malformed property set" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic scene settings snapshot" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5344 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-scene-settings-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1130-000", + "phase": "1130", + "title": "authorize_editor_view2d_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1129-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1130", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1130-000.md", + "behavior": "Authorize one source-backed UI editor View2D reader/protocol module after the P1129 scene settings module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1129 evidence remains hash-bound", + "P1102 editor workflow source remains unchanged", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1130-001", + "phase": "1130", + "title": "verify_editor_view2d_module", + "kind": "module", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1130-000" + ], + "parityId": "UI_EDITOR_VIEW2D_STATE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-ui_editor_view2d_state", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1130-001.md", + "behavior": "Preserve Blender Graph/Dope Sheet View2D cur and mask state through the Web editor protocol without changing the existing editor workflow parser.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive reader state is proven", + "negative no-publish and recovery are proven", + "Chromium and save/reopen compatibility are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "UI_EDITOR_VIEW2D_STATE", + "sourceBacked": true, + "capabilities": [ + "CAP-EDITOR-VIEW2D-CUR", + "CAP-EDITOR-VIEW2D-MASK", + "CAP-EDITOR-VIEW2D-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/editor-view2d.ts", + "web/app/src/workers/editor-view2d-test.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/ui-editor-view2d-production.spec.ts" + ], + "reuseReceipts": [], + "positive": [ + "Graph main-region View2D cur retention", + "Graph main-region pixel mask retention", + "reader/protocol exact state" + ], + "negative": [ + "inverted View2D bounds", + "malformed mask range", + "missing View2D payload" + ], + "recovery": [ + "immutable base editor workflow", + "worker termination", + "deterministic repeated parse", + "save/reopen reader compatibility" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5346 npm --prefix web run test:e2e -- --workers=1 tests/e2e/ui-editor-view2d-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1131-000", + "phase": "1131", + "title": "authorize_curve_topology_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1130-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1131", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1131-000.md", + "behavior": "Authorize one source-backed Curve topology editor module after the P1130 View2D module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1130 evidence remains hash-bound", + "Curve topology source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1131-001", + "phase": "1131", + "title": "verify_curve_topology_module", + "kind": "module", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1131-000" + ], + "parityId": "CURVE_TOPOLOGY_EDITOR", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-curve_topology_editor", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1131-001.md", + "behavior": "Verify the Blender Curve TOGGLE_CYCLIC topology transaction through the existing Main, protocol, Worker and frontend path.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "CURVE_TOPOLOGY_EDITOR", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-TOPOLOGY-TOGGLE-CYCLIC", + "CAP-CURVE-TOPOLOGY-GATE", + "CAP-CURVE-TOPOLOGY-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/editors/curve/curve_ops.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/curve-topology-editor.ts", + "web/app/src/workers/curve-topology-contract-test.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/curve-topology-contract.spec.ts", + "web/tests/e2e/curve-topology-operator.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "TOGGLE_CYCLIC Main mutation", + "operator gate exposes only verified capability", + "save/reopen preserves cyclic spline state" + ], + "negative": [ + "unknown curve operator", + "stale revision claim", + "selection and payload budget overflow" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker termination and deterministic contract parse" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5347 npm --prefix web run test:e2e -- --workers=1 tests/e2e/curve-topology-contract.spec.ts tests/e2e/curve-topology-operator.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1132-000", + "phase": "1132", + "title": "authorize_curve_handle_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1131-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1132", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1132-000.md", + "behavior": "Authorize one source-backed Curve handle gizmo module after the P1131 topology module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1131 evidence remains hash-bound", + "Curve handle source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1132-001", + "phase": "1132", + "title": "verify_curve_handle_module", + "kind": "module", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1132-000" + ], + "parityId": "CURVE_HANDLE_GIZMO", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-curve_handle_gizmo", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1132-001.md", + "behavior": "Verify Curve handle position edits through Blender Main, protocol, Worker, renderer preview and frontend gizmo.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "CURVE_HANDLE_GIZMO", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-HANDLE-MAIN", + "CAP-CURVE-HANDLE-GIZMO-PREVIEW", + "CAP-CURVE-HANDLE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/nonmesh-interaction.ts", + "web/app/src/workers/nonmesh-interaction-test.worker.ts", + "web/app/src/app/App.tsx", + "web/app/src/three-adapter/nonmesh.ts", + "web/app/src/three-adapter/viewport.ts", + "web/app/src/three-adapter/offscreen-viewport.ts", + "web/tests/e2e/wbv2-curve-handle-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "Curve handle position Main mutation", + "local handle gizmo preview", + "save/reopen preserves handle state" + ], + "negative": [ + "invalid handle identity", + "stale base revision", + "malformed handle position" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "Worker termination and deterministic preview" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5348 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-curve-handle-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1133-000", + "phase": "1133", + "title": "authorize_curve_splines_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1132-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1133", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1133-000.md", + "behavior": "Authorize one source-backed Curve spline transaction module after the P1132 handle module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1132 evidence remains hash-bound", + "Curve spline source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1133-001", + "phase": "1133", + "title": "verify_curve_splines_module", + "kind": "module", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1133-000" + ], + "parityId": "CURVE_SPLINES_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-curve_splines_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1133-001.md", + "behavior": "Verify complete Curve spline replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "CURVE_SPLINES_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-CURVE-SPLINES-MAIN", + "CAP-CURVE-SPLINES-RECOVERY", + "CAP-CURVE-SPLINES-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/tests/e2e/wbv2-curve-splines-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "complete Curve spline Main transaction", + "POLY/BEZIER descriptor retention", + "save/reopen preserves spline state" + ], + "negative": [ + "invalid spline offsets", + "stale base revision", + "mismatched handle payload" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic binary-geometry transaction" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5349 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-curve-splines-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1134-000", + "phase": "1134", + "title": "authorize_surface_topology_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1133-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1134", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1134-000.md", + "behavior": "Authorize one source-backed Surface topology transaction module after the P1133 Curve spline module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1133 evidence remains hash-bound", + "Surface topology source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1134-001", + "phase": "1134", + "title": "verify_surface_topology_module", + "kind": "module", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P1134-000" + ], + "parityId": "SURFACE_TOPOLOGY_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-surface_topology_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1134-001.md", + "behavior": "Verify Surface NURBS topology replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SURFACE_TOPOLOGY_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-SURFACE-TOPOLOGY-MAIN", + "CAP-SURFACE-NURBS-BOUNDS", + "CAP-SURFACE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/tests/e2e/wbv2-surface-topology-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "Surface topology Main transaction", + "NURBS dimensions and weights retention", + "save/reopen preserves surface state" + ], + "negative": [ + "invalid surface dimensions", + "stale base revision", + "control grid budget mismatch" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "deterministic surface transaction" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5350 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-surface-topology-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1135-000", + "phase": "1135", + "title": "authorize_font_body_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1134-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1135", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1135-000.md", + "behavior": "Authorize one source-backed Font body transaction module after the P1134 Surface topology module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1134 evidence remains hash-bound", + "Font body source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1135-001", + "phase": "1135", + "title": "verify_font_body_module", + "kind": "module", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P1135-000" + ], + "parityId": "FONT_BODY_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-font_body_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1135-001.md", + "behavior": "Verify Font body replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "FONT_BODY_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-FONT-BODY-MAIN", + "CAP-FONT-BODY-RECOVERY", + "CAP-FONT-BODY-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/wbv2-font-body-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "Font body Main mutation", + "UTF-8 text retention", + "save/reopen preserves text" + ], + "negative": [ + "unknown Font data ID", + "body byte budget overflow", + "malformed body payload" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "Worker termination and deterministic text state" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5351 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-font-body-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1136-000", + "phase": "1136", + "title": "authorize_font_properties_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1135-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1136", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1136-000.md", + "behavior": "Authorize one source-backed Font properties transaction module after the P1135 Font body module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1135 evidence remains hash-bound", + "Font property source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1136-001", + "phase": "1136", + "title": "verify_font_properties_module", + "kind": "module", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P1136-000" + ], + "parityId": "FONT_PROPERTIES_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-font_properties_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1136-001.md", + "behavior": "Verify Font property replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "FONT_PROPERTIES_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-FONT-PROPERTIES-MAIN", + "CAP-FONT-PROPERTIES-RECOVERY", + "CAP-FONT-PROPERTIES-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/wbv2-font-properties-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "Font property Main mutation", + "bounded alignment/extrude fields", + "save/reopen preserves properties" + ], + "negative": [ + "unknown Font data ID", + "invalid alignment enum", + "out-of-range numeric property" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "Worker termination and deterministic property state" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5352 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-font-properties-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1137-000", + "phase": "1137", + "title": "authorize_metaball_elements_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1136-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1137", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1137-000.md", + "behavior": "Authorize one source-backed Metaball element transaction module after the P1136 Font properties module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1136 evidence remains hash-bound", + "Metaball element source and protocol are present", + "inventory remains immutable", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1137-001", + "phase": "1137", + "title": "verify_metaball_elements_module", + "kind": "module", + "owner": "GEOMETRY", + "dependsOn": [ + "WBV2-P1137-000" + ], + "parityId": "METABALL_ELEMENTS_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-metaball_elements_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1137-001.md", + "behavior": "Verify Metaball element replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "METABALL_ELEMENTS_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-METABALL-ELEMENTS-MAIN", + "CAP-METABALL-ELEMENTS-RECOVERY", + "CAP-METABALL-ELEMENTS-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/wbv2-metaball-elements-production.spec.ts" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1101-000/manifest.json", + "report": "tests/golden/WBV2-P1101-000/module-receipt.json" + } + ], + "positive": [ + "Metaball element Main mutation", + "bounded position/radius/scale retention", + "save/reopen preserves elements" + ], + "negative": [ + "unknown Metaball data ID", + "invalid radius", + "element count topology mismatch" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "Worker termination and deterministic element state" + ], + "commands": [ + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5353 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-metaball-elements-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1138-000", + "phase": "1138", + "title": "authorize_text_source_module", + "kind": "enabling", + "owner": "SCRIPTING", + "dependsOn": [ + "WBV2-P1137-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1138", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1138-000.md", + "behavior": "Authorize a source-backed Text datablock mutation after the P1137 Metaball module.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1137 evidence remains hash-bound", + "ID_TXT is registered for WITH_WEB", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1138-001", + "phase": "1138", + "title": "verify_text_source_module", + "kind": "module", + "owner": "SCRIPTING", + "dependsOn": [ + "WBV2-P1138-000" + ], + "parityId": "TEXT_SOURCE_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-text_source_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1138-001.md", + "behavior": "Verify Text source replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "TEXT_SOURCE_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-TEXT-SOURCE-MAIN", + "CAP-TEXT-SOURCE-RECOVERY", + "CAP-TEXT-SOURCE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/blenkernel/intern/idtype.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/wbv2-text-source-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1137-001/manifest.json", + "report": "tests/golden/WBV2-P1137-001/module-receipt.json" + } + ], + "positive": [ + "Text source Main mutation", + "ID_TXT registration in WITH_WEB", + "save/reopen preserves source" + ], + "negative": [ + "unknown Text data ID", + "source over 1 MiB", + "linked/read-only Text" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "Worker termination and deterministic source state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5353 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-text-source-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1139-000", + "phase": "1139", + "title": "authorize_texture_properties_module", + "kind": "enabling", + "owner": "TEXTURE", + "dependsOn": [ + "WBV2-P1138-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1139", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1139-000.md", + "behavior": "Authorize a source-backed Texture property mutation module after P1138 Text.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1138 evidence remains hash-bound", + "ID_TE is registered for WITH_WEB", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1139-001", + "phase": "1139", + "title": "verify_texture_properties_module", + "kind": "module", + "owner": "TEXTURE", + "dependsOn": [ + "WBV2-P1139-000" + ], + "parityId": "TEXTURE_PROPERTIES_TRANSACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-texture_properties_transaction", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1139-001.md", + "behavior": "Verify Texture property replacement through Blender Main, protocol, Worker and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main mutation is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "TEXTURE_PROPERTIES_TRANSACTION", + "sourceBacked": true, + "capabilities": [ + "CAP-TEXTURE-PROPERTIES-MAIN", + "CAP-TEXTURE-PROPERTIES-RECOVERY", + "CAP-TEXTURE-PROPERTIES-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/blenkernel/intern/idtype.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "blender-5.2.0/source/blender/web_engine/web_engine_main_state.h", + "web/protocol/web-engine.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/app/App.tsx", + "web/tests/e2e/wbv2-texture-properties-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1138-001/manifest.json", + "report": "tests/golden/WBV2-P1138-001/module-receipt.json" + } + ], + "positive": [ + "Texture property Main mutation", + "ID_TE registration in WITH_WEB", + "save/reopen preserves properties" + ], + "negative": [ + "unknown Texture data ID", + "noise depth outside Blender bounds", + "non-finite numeric property" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "Worker termination and deterministic property state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5353 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-texture-properties-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1140-000", + "phase": "1140", + "title": "authorize_action_group_reader_module", + "kind": "enabling", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1139-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1140", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1140-000.md", + "behavior": "Authorize a source-backed ActionGroup reader and recovery module after P1139 Texture.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1139 evidence remains hash-bound", + "ActionGroup has explicit Blender source mapping", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1140-001", + "phase": "1140", + "title": "verify_action_group_reader_module", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1140-000" + ], + "parityId": "ACTION_GROUP_READER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-action_group_reader", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1140-001.md", + "behavior": "Verify ActionGroup metadata through Blender Main reader, protocol and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main reader is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "ACTION_GROUP_READER", + "sourceBacked": true, + "capabilities": [ + "CAP-ACTION-GROUP-READER", + "CAP-ACTION-GROUP-RECOVERY", + "CAP-ACTION-GROUP-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/tests/e2e/wbv2-action-group-reader-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1112-000/manifest.json", + "report": "tests/golden/WBV2-P1112-000/module-receipt.json" + } + ], + "positive": [ + "ActionGroup Main reader exposes group and expanded metadata", + "three grouped location F-Curves remain grouped", + "save/reopen preserves group metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "missing animation target is fail-closed", + "unsupported group payload is not synthesized" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker termination and deterministic group state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5356 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-action-group-reader-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1141-000", + "phase": "1141", + "title": "authorize_action_pose_markers_module", + "kind": "enabling", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1140-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1141", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1141-000.md", + "behavior": "Authorize a source-backed ActionPoseMarkers reader and recovery module after P1140.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1140 evidence remains hash-bound", + "ActionPoseMarkers has explicit Blender source mapping", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1141-001", + "phase": "1141", + "title": "verify_action_pose_markers_reader_module", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1141-000" + ], + "parityId": "ACTION_POSE_MARKERS_READER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-action_pose_markers_reader", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1141-001.md", + "behavior": "Verify ActionPoseMarkers metadata through Blender Main reader, protocol and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main reader is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "ACTION_POSE_MARKERS_READER", + "sourceBacked": true, + "capabilities": [ + "CAP-ACTION-POSE-MARKERS-READER", + "CAP-ACTION-POSE-MARKERS-RECOVERY", + "CAP-ACTION-POSE-MARKERS-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/tests/e2e/wbv2-action-pose-markers-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1140-001/manifest.json", + "report": "tests/golden/WBV2-P1140-001/module-receipt.json" + } + ], + "positive": [ + "ActionPoseMarkers Main reader exposes marker names and frames", + "three Blender pose markers remain ordered", + "save/reopen preserves marker metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "missing animation target is fail-closed", + "non-finite marker frame is not synthesized" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker termination and deterministic marker state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5359 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-action-pose-markers-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1142-000", + "phase": "1142", + "title": "authorize_fcurve_sample_reader_module", + "kind": "enabling", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1141-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1142", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1142-000.md", + "behavior": "Authorize a source-backed FCurveSample reader and recovery module after P1141.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1141 evidence remains hash-bound", + "FCurveSample has explicit Blender source mapping", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1142-001", + "phase": "1142", + "title": "verify_fcurve_sample_reader_module", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1142-000" + ], + "parityId": "FCURVE_SAMPLE_READER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-fcurve_sample_reader", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1142-001.md", + "behavior": "Verify FCurveSample data through Blender Main reader, protocol and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main reader is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "FCURVE_SAMPLE_READER", + "sourceBacked": true, + "capabilities": [ + "CAP-FCURVE-SAMPLE-READER", + "CAP-FCURVE-SAMPLE-RECOVERY", + "CAP-FCURVE-SAMPLE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/tests/e2e/wbv2-fcurve-sample-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1141-001/manifest.json", + "report": "tests/golden/WBV2-P1141-001/module-receipt.json" + } + ], + "positive": [ + "FCurveSample Main reader exposes sampled source and values", + "four native FPoint samples remain ordered", + "save/reopen preserves sampled data" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "missing sampled payload is fail-closed", + "non-finite sampled value is not synthesized" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker termination and deterministic sampled state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5365 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-fcurve-sample-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1143-000", + "phase": "1143", + "title": "authorize_fcurve_modifier_reader_module", + "kind": "enabling", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1142-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1143", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1143-000.md", + "behavior": "Authorize a source-backed FCurve modifier reader and recovery module after P1142.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1142 evidence remains hash-bound", + "FCurveModifiers has explicit Blender source mapping", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1143-001", + "phase": "1143", + "title": "verify_fcurve_modifier_reader_module", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1143-000" + ], + "parityId": "FCURVE_MODIFIER_READER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-fcurve_modifier_reader", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1143-001.md", + "behavior": "Verify FCurve modifier metadata through Blender Main reader, protocol and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main reader is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "FCURVE_MODIFIER_READER", + "sourceBacked": true, + "capabilities": [ + "CAP-FCURVE-MODIFIER-READER", + "CAP-FCURVE-MODIFIER-RECOVERY", + "CAP-FCURVE-MODIFIER-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/tests/e2e/wbv2-fcurve-modifier-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1142-001/manifest.json", + "report": "tests/golden/WBV2-P1142-001/module-receipt.json" + } + ], + "positive": [ + "FCurveModifiers Main reader exposes native modifier stack", + "FModifierCycles preserves type/name/flags/influence", + "save/reopen preserves modifier metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "missing modifier payload is fail-closed", + "unsupported modifier type is not synthesized" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker termination and deterministic modifier state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5368 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-fcurve-modifier-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1144-000", + "phase": "1144", + "title": "authorize_driver_reader_module", + "kind": "enabling", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1143-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1144", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1144-000.md", + "behavior": "Authorize a source-backed Driver reader and recovery module after P1143.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "P1143 evidence remains hash-bound", + "Driver has explicit Blender source mapping", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1144-001", + "phase": "1144", + "title": "verify_driver_reader_module", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1144-000" + ], + "parityId": "DRIVER_READER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-driver_reader", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1144-001.md", + "behavior": "Verify Driver metadata through Blender Main reader, protocol and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main reader is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "DRIVER_READER", + "sourceBacked": true, + "capabilities": [ + "CAP-DRIVER-READER", + "CAP-DRIVER-RECOVERY", + "CAP-DRIVER-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/protocol/scene-ir.ts", + "web/app/src/workers/web-engine.worker.ts", + "web/app/src/engine-client/WebEngineClient.ts", + "web/tests/e2e/wbv2-driver-reader-production.spec.ts", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1143-001/manifest.json", + "report": "tests/golden/WBV2-P1143-001/module-receipt.json" + } + ], + "positive": [ + "AnimData driver list is read from Blender Main", + "Driver preserves scripted expression and variables", + "save/reopen preserves driver metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "missing driver target is fail-closed", + "non-finite driver influence is not synthesized" + ], + "recovery": [ + "undo", + "redo", + "save/reopen", + "worker termination and deterministic driver state" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-driver-reader-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1145-000", + "phase": "1145", + "title": "authorize_corrective_smooth_reader_module", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1144-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1145", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1145-000.md", + "behavior": "Authorize a source-backed Corrective Smooth reader/recovery module after the Driver reader.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "Corrective Smooth has explicit Blender source mapping", + "inventory remains source-derived", + "one source-backed module is active" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1145-001", + "phase": "1145", + "title": "verify_corrective_smooth_reader_module", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1145-000" + ], + "parityId": "CORRECTIVE_SMOOTH_READER", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-corrective_smooth_reader", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1145-001.md", + "behavior": "Verify Corrective Smooth modifier type and RNA metadata through Blender Main reader, protocol and Chromium recovery.", + "outputs": [ + "module receipt", + "negative matrix", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "positive Main reader is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact", + "full-family parity remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "CORRECTIVE_SMOOTH_READER", + "sourceBacked": true, + "capabilities": [ + "CAP-CORRECTIVE-SMOOTH-READER", + "CAP-CORRECTIVE-SMOOTH-RECOVERY", + "CAP-CORRECTIVE-SMOOTH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_correctivesmooth.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-corrective-smooth-reader-production.spec.ts", + "tests/files/web/modifier_corrective_smooth_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "Corrective Smooth type is read from Blender Main", + "RNA metadata is preserved", + "save/reopen preserves modifier metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported modifier data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-corrective-smooth-reader-production.spec.ts" + ], + "fullFamilyParity": false + } + }, + { + "id": "WBV2-P1146-000", + "phase": "1146", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1145-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1146", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1146-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1146-001", + "phase": "1146", + "title": "verify modifier reader batch", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1146-000" + ], + "parityId": "MODIFIER_READER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_reader_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1146-001.md", + "behavior": "Verify the MODIFIER_READER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_READER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH-READER", + "CAP-MODIFIER_READER_BATCH-RECOVERY", + "CAP-MODIFIER_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_datatransfer.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_dynamicpaint.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_explode.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_fluid.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_fluid.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-production.spec.ts", + "tests/files/web/modifier_reader_batch_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_datatransfer type is read from Blender Main", + "MOD_dynamicpaint type is read from Blender Main", + "MOD_explode type is read from Blender Main", + "MOD_fluid type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-batch-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1146-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_datatransfer", + "modifier-source:MOD_dynamicpaint", + "modifier-source:MOD_explode", + "modifier-source:MOD_fluid", + "rna-struct:DataTransferModifier", + "rna-struct:DynamicPaintModifier", + "rna-struct:ExplodeModifier", + "rna-struct:FluidModifier", + "rna-struct:FluidDomainSettings" + ] + } + }, + { + "id": "WBV2-P1147-000", + "phase": "1147", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1146-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1147", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1147-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1147-001", + "phase": "1147", + "title": "verify modifier reader batch two", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1147-000" + ], + "parityId": "MODIFIER_READER_BATCH_TWO", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_reader_batch_two", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1147-001.md", + "behavior": "Verify the MODIFIER_READER_BATCH_TWO batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_READER_BATCH_TWO", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_TWO-READER", + "CAP-MODIFIER_READER_BATCH_TWO-RECOVERY", + "CAP-MODIFIER_READER_BATCH_TWO-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_laplaciandeform.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_laplaciansmooth.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_mask.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_shrinkwrap.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_two_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_laplaciandeform type is read from Blender Main", + "MOD_laplaciansmooth type is read from Blender Main", + "MOD_mask type is read from Blender Main", + "MOD_mesh_to_volume type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1147-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_laplaciandeform", + "modifier-source:MOD_laplaciansmooth", + "modifier-source:MOD_mask", + "modifier-source:MOD_shrinkwrap", + "rna-struct:LaplacianDeformModifier", + "rna-struct:LaplacianSmoothModifier", + "rna-struct:MaskModifier", + "rna-struct:ShrinkwrapModifier" + ] + } + }, + { + "id": "WBV2-P1148-000", + "phase": "1148", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1147-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1148", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1148-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1148-001", + "phase": "1148", + "title": "verify modifier reader batch three", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1148-000" + ], + "parityId": "MODIFIER_READER_BATCH_THREE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_reader_batch_three", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1148-001.md", + "behavior": "Verify the MODIFIER_READER_BATCH_THREE batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_READER_BATCH_THREE", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_THREE-READER", + "CAP-MODIFIER_READER_BATCH_THREE-RECOVERY", + "CAP-MODIFIER_READER_BATCH_THREE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_remesh.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_skin.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weighted_normal.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_warp.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_three_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_remesh type is read from Blender Main", + "MOD_skin type is read from Blender Main", + "MOD_weighted_normal type is read from Blender Main", + "MOD_warp type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1148-001 WBV2_BATCH_FIXTURE=tests/files/web/modifier_reader_batch_three_scene.blend WBV2_BATCH_TYPES='[\"REMESH\",\"SKIN\",\"WEIGHTED_NORMAL\",\"WARP\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_remesh\",\"modifier-source:MOD_skin\",\"modifier-source:MOD_weighted_normal\",\"modifier-source:MOD_warp\",\"rna-struct:RemeshModifier\",\"rna-struct:SkinModifier\",\"rna-struct:WeightedNormalModifier\",\"rna-struct:WarpModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1148-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_remesh", + "modifier-source:MOD_skin", + "modifier-source:MOD_weighted_normal", + "modifier-source:MOD_warp", + "rna-struct:RemeshModifier", + "rna-struct:SkinModifier", + "rna-struct:WeightedNormalModifier", + "rna-struct:WarpModifier" + ] + } + }, + { + "id": "WBV2-P1149-000", + "phase": "1149", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1148-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1149", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1149-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1149-001", + "phase": "1149", + "title": "verify modifier reader batch four", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1149-000" + ], + "parityId": "MODIFIER_READER_BATCH_FOUR", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_reader_batch_four", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1149-001.md", + "behavior": "Verify the MODIFIER_READER_BATCH_FOUR batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_READER_BATCH_FOUR", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_FOUR-READER", + "CAP-MODIFIER_READER_BATCH_FOUR-RECOVERY", + "CAP-MODIFIER_READER_BATCH_FOUR-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_uvproject.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_uvwarp.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_normal_edit.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_volume_to_mesh.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_four_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_uvproject type is read from Blender Main", + "MOD_uvwarp type is read from Blender Main", + "MOD_volume_displace type is read from Blender Main", + "MOD_volume_to_mesh type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1149-001 WBV2_BATCH_FIXTURE=tests/files/web/modifier_reader_batch_four_scene.blend WBV2_BATCH_TYPES='[\"UV_PROJECT\",\"UV_WARP\",\"NORMAL_EDIT\",\"VOLUME_TO_MESH\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_uvproject\",\"modifier-source:MOD_uvwarp\",\"modifier-source:MOD_normal_edit\",\"modifier-source:MOD_volume_to_mesh\",\"rna-struct:UVProjectModifier\",\"rna-struct:UVWarpModifier\",\"rna-struct:NormalEditModifier\",\"rna-struct:VolumeToMeshModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1149-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_uvproject", + "modifier-source:MOD_uvwarp", + "modifier-source:MOD_normal_edit", + "modifier-source:MOD_volume_to_mesh", + "rna-struct:UVProjectModifier", + "rna-struct:UVWarpModifier", + "rna-struct:NormalEditModifier", + "rna-struct:VolumeToMeshModifier" + ] + } + }, + { + "id": "WBV2-P1150-000", + "phase": "1150", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1149-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1150", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1150-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1150-001", + "phase": "1150", + "title": "verify modifier reader batch five", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1150-000" + ], + "parityId": "MODIFIER_READER_BATCH_FIVE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_reader_batch_five", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1150-001.md", + "behavior": "Verify the MODIFIER_READER_BATCH_FIVE batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_READER_BATCH_FIVE", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_FIVE-READER", + "CAP-MODIFIER_READER_BATCH_FIVE-RECOVERY", + "CAP-MODIFIER_READER_BATCH_FIVE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshsequencecache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_multires.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_ocean.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_reader_batch_five_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_meshcache type is read from Blender Main", + "MOD_meshsequencecache type is read from Blender Main", + "MOD_multires type is read from Blender Main", + "MOD_ocean type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1150-001 WBV2_BATCH_FIXTURE=tests/files/web/modifier_reader_batch_five_scene.blend WBV2_BATCH_TYPES='[\"MESH_CACHE\",\"MESH_SEQUENCE_CACHE\",\"MULTIRES\",\"OCEAN\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_meshcache\",\"modifier-source:MOD_meshsequencecache\",\"modifier-source:MOD_multires\",\"modifier-source:MOD_ocean\",\"rna-struct:MeshCacheModifier\",\"rna-struct:MeshSequenceCacheModifier\",\"rna-struct:MultiresModifier\",\"rna-struct:OceanModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_meshcache", + "modifier-source:MOD_meshsequencecache", + "modifier-source:MOD_multires", + "modifier-source:MOD_ocean", + "rna-struct:MeshCacheModifier", + "rna-struct:MeshSequenceCacheModifier", + "rna-struct:MultiresModifier", + "rna-struct:OceanModifier" + ] + } + }, + { + "id": "WBV2-P1151-000", + "phase": "1151", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1150-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1151", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1151-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1151-001", + "phase": "1151", + "title": "verify Grease Pencil modifier reader batch", + "kind": "module", + "owner": "DRAWING", + "dependsOn": [ + "WBV2-P1151-000" + ], + "parityId": "GREASE_PENCIL_MODIFIER_READER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-grease_pencil_modifier_reader_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1151-001.md", + "behavior": "Verify the GREASE_PENCIL_MODIFIER_READER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "GREASE_PENCIL_MODIFIER_READER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-GREASE_PENCIL_MODIFIER_READER_BATCH-READER", + "CAP-GREASE_PENCIL_MODIFIER_READER_BATCH-RECOVERY", + "CAP-GREASE_PENCIL_MODIFIER_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_armature.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_array.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_build.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_color.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_dash.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_envelope.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_hook.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_lattice.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_length.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_mirror.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_multiply.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_noise.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_offset.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_opacity.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_outline.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_shrinkwrap.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_simplify.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_smooth.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_subdiv.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_texture.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_thickness.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_time.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_tint.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_weight_angle.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_weight_proximity.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts", + "tests/files/web/modifier_grease_pencil_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_grease_pencil_armature type is read from Blender Main", + "MOD_grease_pencil_array type is read from Blender Main", + "MOD_grease_pencil_build type is read from Blender Main", + "MOD_grease_pencil_color type is read from Blender Main", + "MOD_grease_pencil_dash type is read from Blender Main", + "MOD_grease_pencil_envelope type is read from Blender Main", + "MOD_grease_pencil_hook type is read from Blender Main", + "MOD_grease_pencil_lattice type is read from Blender Main", + "MOD_grease_pencil_length type is read from Blender Main", + "MOD_grease_pencil_mirror type is read from Blender Main", + "MOD_grease_pencil_multiply type is read from Blender Main", + "MOD_grease_pencil_noise type is read from Blender Main", + "MOD_grease_pencil_offset type is read from Blender Main", + "MOD_grease_pencil_opacity type is read from Blender Main", + "MOD_grease_pencil_outline type is read from Blender Main", + "MOD_grease_pencil_shrinkwrap type is read from Blender Main", + "MOD_grease_pencil_simplify type is read from Blender Main", + "MOD_grease_pencil_smooth type is read from Blender Main", + "MOD_grease_pencil_subdiv type is read from Blender Main", + "MOD_grease_pencil_texture type is read from Blender Main", + "MOD_grease_pencil_thickness type is read from Blender Main", + "MOD_grease_pencil_time type is read from Blender Main", + "MOD_grease_pencil_tint type is read from Blender Main", + "MOD_grease_pencil_weight_angle type is read from Blender Main", + "MOD_grease_pencil_weight_proximity type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1151-001 WBV2_BATCH_FIXTURE=tests/files/web/modifier_grease_pencil_scene.blend WBV2_BATCH_TYPES='[\"GREASE_PENCIL_ARMATURE\",\"GREASE_PENCIL_ARRAY\",\"GREASE_PENCIL_BUILD\",\"GREASE_PENCIL_COLOR\",\"GREASE_PENCIL_DASH\",\"GREASE_PENCIL_ENVELOPE\",\"GREASE_PENCIL_HOOK\",\"GREASE_PENCIL_LATTICE\",\"GREASE_PENCIL_LENGTH\",\"GREASE_PENCIL_MIRROR\",\"GREASE_PENCIL_MULTIPLY\",\"GREASE_PENCIL_NOISE\",\"GREASE_PENCIL_OFFSET\",\"GREASE_PENCIL_OPACITY\",\"GREASE_PENCIL_OUTLINE\",\"GREASE_PENCIL_SHRINKWRAP\",\"GREASE_PENCIL_SIMPLIFY\",\"GREASE_PENCIL_SMOOTH\",\"GREASE_PENCIL_SUBDIV\",\"GREASE_PENCIL_TEXTURE\",\"GREASE_PENCIL_THICKNESS\",\"GREASE_PENCIL_TIME\",\"GREASE_PENCIL_TINT\",\"GREASE_PENCIL_VERTEX_WEIGHT_ANGLE\",\"GREASE_PENCIL_VERTEX_WEIGHT_PROXIMITY\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_grease_pencil_armature\",\"modifier-source:MOD_grease_pencil_array\",\"modifier-source:MOD_grease_pencil_build\",\"modifier-source:MOD_grease_pencil_color\",\"modifier-source:MOD_grease_pencil_dash\",\"modifier-source:MOD_grease_pencil_envelope\",\"modifier-source:MOD_grease_pencil_hook\",\"modifier-source:MOD_grease_pencil_lattice\",\"modifier-source:MOD_grease_pencil_length\",\"modifier-source:MOD_grease_pencil_mirror\",\"modifier-source:MOD_grease_pencil_multiply\",\"modifier-source:MOD_grease_pencil_noise\",\"modifier-source:MOD_grease_pencil_offset\",\"modifier-source:MOD_grease_pencil_opacity\",\"modifier-source:MOD_grease_pencil_outline\",\"modifier-source:MOD_grease_pencil_shrinkwrap\",\"modifier-source:MOD_grease_pencil_simplify\",\"modifier-source:MOD_grease_pencil_smooth\",\"modifier-source:MOD_grease_pencil_subdiv\",\"modifier-source:MOD_grease_pencil_texture\",\"modifier-source:MOD_grease_pencil_thickness\",\"modifier-source:MOD_grease_pencil_time\",\"modifier-source:MOD_grease_pencil_tint\",\"modifier-source:MOD_grease_pencil_weight_angle\",\"modifier-source:MOD_grease_pencil_weight_proximity\",\"rna-struct:GreasePencilArmatureModifier\",\"rna-struct:GreasePencilArrayModifier\",\"rna-struct:GreasePencilBuildModifier\",\"rna-struct:GreasePencilColorModifier\",\"rna-struct:GreasePencilEnvelopeModifier\",\"rna-struct:GreasePencilHookModifier\",\"rna-struct:GreasePencilLatticeModifier\",\"rna-struct:GreasePencilLengthModifier\",\"rna-struct:GreasePencilMirrorModifier\",\"rna-struct:GreasePencilMultiplyModifier\",\"rna-struct:GreasePencilNoiseModifier\",\"rna-struct:GreasePencilOffsetModifier\",\"rna-struct:GreasePencilOpacityModifier\",\"rna-struct:GreasePencilOutlineModifier\",\"rna-struct:GreasePencilShrinkwrapModifier\",\"rna-struct:GreasePencilSimplifyModifier\",\"rna-struct:GreasePencilSmoothModifier\",\"rna-struct:GreasePencilSubdivModifier\",\"rna-struct:GreasePencilTextureModifier\",\"rna-struct:GreasePencilTimeModifier\",\"rna-struct:GreasePencilTintModifier\",\"rna-struct:GreasePencilWeightAngleModifier\",\"rna-struct:GreasePencilWeightProximityModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-batch-two-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1151-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_grease_pencil_armature", + "modifier-source:MOD_grease_pencil_array", + "modifier-source:MOD_grease_pencil_build", + "modifier-source:MOD_grease_pencil_color", + "modifier-source:MOD_grease_pencil_dash", + "modifier-source:MOD_grease_pencil_envelope", + "modifier-source:MOD_grease_pencil_hook", + "modifier-source:MOD_grease_pencil_lattice", + "modifier-source:MOD_grease_pencil_length", + "modifier-source:MOD_grease_pencil_mirror", + "modifier-source:MOD_grease_pencil_multiply", + "modifier-source:MOD_grease_pencil_noise", + "modifier-source:MOD_grease_pencil_offset", + "modifier-source:MOD_grease_pencil_opacity", + "modifier-source:MOD_grease_pencil_outline", + "modifier-source:MOD_grease_pencil_shrinkwrap", + "modifier-source:MOD_grease_pencil_simplify", + "modifier-source:MOD_grease_pencil_smooth", + "modifier-source:MOD_grease_pencil_subdiv", + "modifier-source:MOD_grease_pencil_texture", + "modifier-source:MOD_grease_pencil_thickness", + "modifier-source:MOD_grease_pencil_time", + "modifier-source:MOD_grease_pencil_tint", + "modifier-source:MOD_grease_pencil_weight_angle", + "modifier-source:MOD_grease_pencil_weight_proximity", + "rna-struct:GreasePencilArmatureModifier", + "rna-struct:GreasePencilArrayModifier", + "rna-struct:GreasePencilBuildModifier", + "rna-struct:GreasePencilColorModifier", + "rna-struct:GreasePencilEnvelopeModifier", + "rna-struct:GreasePencilHookModifier", + "rna-struct:GreasePencilLatticeModifier", + "rna-struct:GreasePencilLengthModifier", + "rna-struct:GreasePencilMirrorModifier", + "rna-struct:GreasePencilMultiplyModifier", + "rna-struct:GreasePencilNoiseModifier", + "rna-struct:GreasePencilOffsetModifier", + "rna-struct:GreasePencilOpacityModifier", + "rna-struct:GreasePencilOutlineModifier", + "rna-struct:GreasePencilShrinkwrapModifier", + "rna-struct:GreasePencilSimplifyModifier", + "rna-struct:GreasePencilSmoothModifier", + "rna-struct:GreasePencilSubdivModifier", + "rna-struct:GreasePencilTextureModifier", + "rna-struct:GreasePencilTimeModifier", + "rna-struct:GreasePencilTintModifier", + "rna-struct:GreasePencilWeightAngleModifier", + "rna-struct:GreasePencilWeightProximityModifier" + ] + } + }, + { + "id": "WBV2-P1152-000", + "phase": "1152", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1151-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1152", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1152-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1152-001", + "phase": "1152", + "title": "verify modifier reader batch six", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1152-000" + ], + "parityId": "MODIFIER_READER_BATCH_SIX", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_reader_batch_six", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1152-001.md", + "behavior": "Verify the MODIFIER_READER_BATCH_SIX batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_READER_BATCH_SIX", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_READER_BATCH_SIX-READER", + "CAP-MODIFIER_READER_BATCH_SIX-RECOVERY", + "CAP-MODIFIER_READER_BATCH_SIX-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_mesh_to_volume.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_particleinstance.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_surface.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgedit.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgmix.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgproximity.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/generated/M16-GAP-00081-modifier-MESH_TO_VOLUME.blend", + "tests/files/web/generated/M16-GAP-00087-modifier-PARTICLE_INSTANCE.blend", + "tests/files/web/generated/M16-GAP-00098-modifier-SURFACE.blend", + "tests/files/web/generated/M16-GAP-00103-modifier-VERTEX_WEIGHT_EDIT.blend", + "tests/files/web/generated/M16-GAP-00104-modifier-VERTEX_WEIGHT_MIX.blend", + "tests/files/web/generated/M16-GAP-00105-modifier-VERTEX_WEIGHT_PROXIMITY.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "positive": [ + "MOD_mesh_to_volume type is read from Blender Main", + "MOD_particleinstance type is read from Blender Main", + "MOD_surface type is read from Blender Main", + "MOD_weightvgedit type is read from Blender Main", + "MOD_weightvgmix type is read from Blender Main", + "MOD_weightvgproximity type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1152-001 WBV2_BATCH_FIXTURES='[\"tests/files/web/generated/M16-GAP-00081-modifier-MESH_TO_VOLUME.blend\",\"tests/files/web/generated/M16-GAP-00087-modifier-PARTICLE_INSTANCE.blend\",\"tests/files/web/generated/M16-GAP-00098-modifier-SURFACE.blend\",\"tests/files/web/generated/M16-GAP-00103-modifier-VERTEX_WEIGHT_EDIT.blend\",\"tests/files/web/generated/M16-GAP-00104-modifier-VERTEX_WEIGHT_MIX.blend\",\"tests/files/web/generated/M16-GAP-00105-modifier-VERTEX_WEIGHT_PROXIMITY.blend\"]' WBV2_BATCH_TYPES='[\"MESH_TO_VOLUME\",\"PARTICLE_INSTANCE\",\"SURFACE\",\"VERTEX_WEIGHT_EDIT\",\"VERTEX_WEIGHT_MIX\",\"VERTEX_WEIGHT_PROXIMITY\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_mesh_to_volume\",\"modifier-source:MOD_particleinstance\",\"modifier-source:MOD_surface\",\"modifier-source:MOD_weightvgedit\",\"modifier-source:MOD_weightvgmix\",\"modifier-source:MOD_weightvgproximity\",\"rna-struct:MeshToVolumeModifier\",\"rna-struct:ParticleInstanceModifier\",\"rna-struct:SurfaceModifier\",\"rna-struct:VertexWeightEditModifier\",\"rna-struct:VertexWeightMixModifier\",\"rna-struct:VertexWeightProximityModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1152-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_mesh_to_volume", + "modifier-source:MOD_particleinstance", + "modifier-source:MOD_surface", + "modifier-source:MOD_weightvgedit", + "modifier-source:MOD_weightvgmix", + "modifier-source:MOD_weightvgproximity", + "rna-struct:MeshToVolumeModifier", + "rna-struct:ParticleInstanceModifier", + "rna-struct:SurfaceModifier", + "rna-struct:VertexWeightEditModifier", + "rna-struct:VertexWeightMixModifier", + "rna-struct:VertexWeightProximityModifier" + ] + } + }, + { + "id": "WBV2-P1153-000", + "phase": "1153", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1152-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1153", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1153-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1153-001", + "phase": "1153", + "title": "reuse verified modifier receipts for shared source utilities", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1153-000" + ], + "parityId": "MODIFIER_SOURCE_DEPENDENCY_REUSE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_source_dependency_reuse", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1153-001.md", + "behavior": "Verify the MODIFIER_SOURCE_DEPENDENCY_REUSE batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_SOURCE_DEPENDENCY_REUSE", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_SOURCE_DEPENDENCY_REUSE-READER", + "CAP-MODIFIER_SOURCE_DEPENDENCY_REUSE-RECOVERY", + "CAP-MODIFIER_SOURCE_DEPENDENCY_REUSE-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_util.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache_mdd.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache_pc2.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache_util.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvg_util.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_array.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgedit.cc", + "tests/golden/WBV2-P1151-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json", + "tests/golden/WBV2-P1152-001/modifier-reader-batch-production.json", + "tools/web/reuse-wbv2-source-dependencies.mjs" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1150-001/manifest.json", + "report": "tests/golden/WBV2-P1150-001/module-receipt.json" + }, + { + "manifest": "tests/golden/WBV2-P1151-001/manifest.json", + "report": "tests/golden/WBV2-P1151-001/module-receipt.json" + }, + { + "manifest": "tests/golden/WBV2-P1152-001/manifest.json", + "report": "tests/golden/WBV2-P1152-001/module-receipt.json" + } + ], + "dependencyReuse": [ + { + "unitId": "modifier-source:MOD_grease_pencil_util", + "representativeUnitId": "modifier-source:MOD_grease_pencil_array", + "proofSource": "blender-5.2.0/source/blender/modifiers/intern/MOD_grease_pencil_array.cc", + "marker": "MOD_grease_pencil_util.hh", + "productionEvidence": "tests/golden/WBV2-P1151-001/modifier-reader-batch-production.json" + }, + { + "unitId": "modifier-source:MOD_meshcache_mdd", + "representativeUnitId": "modifier-source:MOD_meshcache", + "proofSource": "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "marker": "MOD_meshcache_read_mdd_times", + "productionEvidence": "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json" + }, + { + "unitId": "modifier-source:MOD_meshcache_pc2", + "representativeUnitId": "modifier-source:MOD_meshcache", + "proofSource": "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "marker": "MOD_meshcache_read_pc2_times", + "productionEvidence": "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json" + }, + { + "unitId": "modifier-source:MOD_meshcache_util", + "representativeUnitId": "modifier-source:MOD_meshcache", + "proofSource": "blender-5.2.0/source/blender/modifiers/intern/MOD_meshcache.cc", + "marker": "MOD_meshcache_util.hh", + "productionEvidence": "tests/golden/WBV2-P1150-001/modifier-reader-batch-production.json" + }, + { + "unitId": "modifier-source:MOD_weightvg_util", + "representativeUnitId": "modifier-source:MOD_weightvgedit", + "proofSource": "blender-5.2.0/source/blender/modifiers/intern/MOD_weightvgedit.cc", + "marker": "MOD_weightvg_util.hh", + "productionEvidence": "tests/golden/WBV2-P1152-001/modifier-reader-batch-production.json" + } + ], + "positive": [ + "MOD_grease_pencil_util type is read from Blender Main", + "MOD_meshcache_mdd type is read from Blender Main", + "MOD_meshcache_pc2 type is read from Blender Main", + "MOD_meshcache_util type is read from Blender Main", + "MOD_weightvg_util type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "node tools/web/reuse-wbv2-source-dependencies.mjs --task WBV2-P1153-001 --write" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1153-001/source-dependency-reuse-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_grease_pencil_util", + "modifier-source:MOD_meshcache_mdd", + "modifier-source:MOD_meshcache_pc2", + "modifier-source:MOD_meshcache_util", + "modifier-source:MOD_weightvg_util" + ] + } + }, + { + "id": "WBV2-P1154-000", + "phase": "1154", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1153-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1154", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1154-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1154-001", + "phase": "1154", + "title": "verify solidify split helper sources", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1154-000" + ], + "parityId": "MODIFIER_SOLIDIFY_HELPER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_solidify_dependency_reuse", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1154-001.md", + "behavior": "Verify the MODIFIER_SOLIDIFY_HELPER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_SOLIDIFY_HELPER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_SOLIDIFY_HELPER_BATCH-READER", + "CAP-MODIFIER_SOLIDIFY_HELPER_BATCH-RECOVERY", + "CAP-MODIFIER_SOLIDIFY_HELPER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_solidify_extrude.cc", + "blender-5.2.0/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/modifier_generate_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/modifier-source-roundtrip-production.json" + } + ], + "positive": [ + "MOD_solidify_extrude type is read from Blender Main", + "MOD_solidify_nonmanifold type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1154-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1154-001/modifier-reader-batch-production.json WBV2_BATCH_FIXTURE=tests/files/web/modifier_generate_scene.blend WBV2_BATCH_TYPES='[\"SOLIDIFY\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_solidify_extrude\",\"modifier-source:MOD_solidify_nonmanifold\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1154-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_solidify_extrude", + "modifier-source:MOD_solidify_nonmanifold" + ] + } + }, + { + "id": "WBV2-P1155-000", + "phase": "1155", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1154-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1155", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1155-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1155-001", + "phase": "1155", + "title": "verify modifier RNA reader batch", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1155-000" + ], + "parityId": "MODIFIER_RNA_READER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_rna_reader_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1155-001.md", + "behavior": "Verify the MODIFIER_RNA_READER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_RNA_READER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_RNA_READER_BATCH-READER", + "CAP-MODIFIER_RNA_READER_BATCH-RECOVERY", + "CAP-MODIFIER_RNA_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/modifier_grease_pencil_scene.blend", + "tests/files/web/generated/M16-GAP-00088-modifier-PARTICLE_SYSTEM.blend", + "tests/files/web/generated/M16-GAP-00041-modifier-DECIMATE.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "dependencyReuse": [], + "positive": [ + "MOD_lineart type is read from Blender Main", + "MOD_particlesystem type is read from Blender Main", + "MOD_decimate type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1155-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1155-001/modifier-reader-batch-production.json WBV2_BATCH_FIXTURES='[\"tests/files/web/modifier_grease_pencil_scene.blend\",\"tests/files/web/generated/M16-GAP-00088-modifier-PARTICLE_SYSTEM.blend\",\"tests/files/web/generated/M16-GAP-00041-modifier-DECIMATE.blend\"]' WBV2_BATCH_TYPES='[\"LINEART\",\"PARTICLE_SYSTEM\",\"DECIMATE\"]' WBV2_BATCH_UNITS='[\"rna-struct:GreasePencilLineartModifier\",\"rna-struct:ParticleSystemModifier\",\"rna-struct:DecimateModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1155-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "rna-struct:GreasePencilLineartModifier", + "rna-struct:ParticleSystemModifier", + "rna-struct:DecimateModifier" + ] + } + }, + { + "id": "WBV2-P1156-000", + "phase": "1156", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1155-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1156", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1156-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1156-001", + "phase": "1156", + "title": "verify volume displace modifier reader", + "kind": "module", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P1156-000" + ], + "parityId": "MODIFIER_VOLUME_DISPLACE_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-modifier_volume_displace_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1156-001.md", + "behavior": "Verify the MODIFIER_VOLUME_DISPLACE_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "MODIFIER_VOLUME_DISPLACE_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-MODIFIER_VOLUME_DISPLACE_BATCH-READER", + "CAP-MODIFIER_VOLUME_DISPLACE_BATCH-RECOVERY", + "CAP-MODIFIER_VOLUME_DISPLACE_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/modifiers/intern/MOD_volume_displace.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts", + "tests/files/web/generated/M16-GAP-00106-modifier-VOLUME_DISPLACE.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "dependencyReuse": [], + "positive": [ + "MOD_volume_displace type is read from Blender Main", + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1156-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1156-001/modifier-reader-batch-production.json WBV2_BATCH_FIXTURE=tests/files/web/generated/M16-GAP-00106-modifier-VOLUME_DISPLACE.blend WBV2_BATCH_TYPES='[\"VOLUME_DISPLACE\"]' WBV2_BATCH_UNITS='[\"modifier-source:MOD_volume_displace\",\"rna-struct:VolumeDisplaceModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-reader-multi-fixture-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1156-001/modifier-reader-batch-production.json" + ], + "coverageBindings": [ + "modifier-source:MOD_volume_displace", + "rna-struct:VolumeDisplaceModifier" + ] + } + }, + { + "id": "WBV2-P1157-000", + "phase": "1157", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1156-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1157", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1157-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1157-001", + "phase": "1157", + "title": "verify shape key point reader", + "kind": "module", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P1157-000" + ], + "parityId": "SHAPE_KEY_POINT_READER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-shape_key_point_reader_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1157-001.md", + "behavior": "Verify the SHAPE_KEY_POINT_READER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "SHAPE_KEY_POINT_READER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-SHAPE_KEY_POINT_READER_BATCH-READER", + "CAP-SHAPE_KEY_POINT_READER_BATCH-RECOVERY", + "CAP-SHAPE_KEY_POINT_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_key.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-shape-key-reader-production.spec.ts", + "tests/files/web/rigged_shape_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "dependencyReuse": [], + "positive": [ + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1157-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1157-001/shape-key-reader-production.json WBV2_BATCH_FIXTURE=tests/files/web/rigged_shape_scene.blend WBV2_BATCH_TYPES='[]' WBV2_BATCH_UNITS='[\"rna-struct:ShapeKeyPoint\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-shape-key-reader-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1157-001/shape-key-reader-production.json" + ], + "coverageBindings": [ + "rna-struct:ShapeKeyPoint" + ] + } + }, + { + "id": "WBV2-P1158-000", + "phase": "1158", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1157-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1158", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1158-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1158-001", + "phase": "1158", + "title": "verify line style reader batch", + "kind": "module", + "owner": "DRAWING", + "dependsOn": [ + "WBV2-P1158-000" + ], + "parityId": "LINE_STYLE_READER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-line_style_reader_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1158-001.md", + "behavior": "Verify the LINE_STYLE_READER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "LINE_STYLE_READER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-LINE_STYLE_READER_BATCH-READER", + "CAP-LINE_STYLE_READER_BATCH-RECOVERY", + "CAP-LINE_STYLE_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "tests/files/web/generated/M16-GAP-00008-datablock-FreestyleLineStyle.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "dependencyReuse": [], + "positive": [ + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1158-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1158-001/line-style-reader-production.json WBV2_BATCH_FIXTURE=tests/files/web/generated/M16-GAP-00008-datablock-FreestyleLineStyle.blend WBV2_BATCH_TYPES='[]' WBV2_BATCH_UNITS='[\"rna-struct:FreestyleLineStyle\",\"rna-struct:LineStyleModifier\",\"rna-struct:LineStyleAlphaModifier\",\"rna-struct:LineStyleColorModifier\",\"rna-struct:LineStyleGeometryModifier\",\"rna-struct:LineStyleThicknessModifier\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-line-style-reader-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1158-001/line-style-reader-production.json" + ], + "coverageBindings": [ + "rna-struct:FreestyleLineStyle", + "rna-struct:LineStyleModifier", + "rna-struct:LineStyleAlphaModifier", + "rna-struct:LineStyleColorModifier", + "rna-struct:LineStyleGeometryModifier", + "rna-struct:LineStyleThicknessModifier" + ] + } + }, + { + "id": "WBV2-P1159-000", + "phase": "1159", + "title": "authorize_modifier_reader_batch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P1158-001" + ], + "parityId": null, + "implementationClass": "QUEUE_ONLY", + "parallelGroup": "module-root-1159", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1159-000.md", + "behavior": "Authorize one shared source-backed modifier reader batch.", + "outputs": [ + "successor authorization", + "module plan", + "manifest", + "status" + ], + "acceptance": [ + "prior evidence remains hash-bound", + "batch source mapping is explicit", + "inventory remains source-derived" + ], + "commands": [ + "node tools/web/check-execution-control-plane.mjs" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P1159-001", + "phase": "1159", + "title": "verify line style collection reader batch", + "kind": "module", + "owner": "DRAWING", + "dependsOn": [ + "WBV2-P1159-000" + ], + "parityId": "LINE_STYLE_COLLECTION_READER_BATCH", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "module-line_style_collection_reader_batch", + "gate": "MODULE", + "card": "docs/tasks/WBV2-P1159-001.md", + "behavior": "Verify the LINE_STYLE_COLLECTION_READER_BATCH batch through Blender Main, WASM and Chromium recovery.", + "outputs": [ + "aggregate module receipt", + "coverage bindings", + "manifest", + "status" + ], + "acceptance": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true, + "module": { + "moduleId": "LINE_STYLE_COLLECTION_READER_BATCH", + "sourceBacked": true, + "capabilities": [ + "CAP-LINE_STYLE_COLLECTION_READER_BATCH-READER", + "CAP-LINE_STYLE_COLLECTION_READER_BATCH-RECOVERY", + "CAP-LINE_STYLE_COLLECTION_READER_BATCH-FAIL-CLOSED" + ], + "sourcePaths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_main_api.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "tests/files/web/line_style_modifier_batch_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "reuseReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json" + } + ], + "dependencyReuse": [], + "positive": [ + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ], + "commands": [ + "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "npm --prefix web run typecheck", + "npm --prefix web run build", + "WBV2_BATCH_TASK=WBV2-P1159-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1159-001/line-style-reader-production.json WBV2_BATCH_FIXTURE=tests/files/web/line_style_modifier_batch_scene.blend WBV2_BATCH_TYPES='[]' WBV2_BATCH_UNITS='[\"rna-struct:BlendDataLineStyles\",\"rna-struct:LineStyleColorModifiers\",\"rna-struct:LineStyleAlphaModifiers\",\"rna-struct:LineStyleThicknessModifiers\",\"rna-struct:LineStyleGeometryModifiers\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-line-style-reader-production.spec.ts" + ], + "fullFamilyParity": false, + "evidencePaths": [ + "tests/golden/WBV2-P1159-001/line-style-reader-production.json" + ], + "coverageBindings": [ + "rna-struct:BlendDataLineStyles", + "rna-struct:LineStyleColorModifiers", + "rna-struct:LineStyleAlphaModifiers", + "rna-struct:LineStyleThicknessModifiers", + "rna-struct:LineStyleGeometryModifiers" + ] + } + } + ] +} diff --git a/tests/golden/WBV2-P1159-001/line-style-reader-production.json b/tests/golden/WBV2-P1159-001/line-style-reader-production.json new file mode 100644 index 000000000..7d4b67895 --- /dev/null +++ b/tests/golden/WBV2-P1159-001/line-style-reader-production.json @@ -0,0 +1,81 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P1159-001", + "operation": "LINE_STYLE_READER_CHROMIUM_SAVE_REOPEN", + "browser": "chromium", + "queueMutation": false, + "fixture": "tests/files/web/line_style_modifier_batch_scene.blend", + "fixtureSha256": "997d904b79d5c1578eb2c51d7abd9d02129cd2385f39a2a7b33424ba2780e0aa", + "sourceUnits": [ + "rna-struct:BlendDataLineStyles", + "rna-struct:LineStyleColorModifiers", + "rna-struct:LineStyleAlphaModifiers", + "rna-struct:LineStyleThicknessModifiers", + "rna-struct:LineStyleGeometryModifiers" + ], + "before": [ + { + "id": "line-style:WebGapLineStyle", + "name": "WebGapLineStyle", + "color": [ + 0.20000000298023224, + 0.4000000059604645, + 0.800000011920929 + ], + "alpha": 0.75, + "thickness": 2.5, + "modifierCounts": { + "alpha": 1, + "color": 1, + "geometry": 2, + "thickness": 1 + } + } + ], + "styleCount": 1, + "after": [ + { + "id": "line-style:WebGapLineStyle", + "name": "WebGapLineStyle", + "color": [ + 0.20000000298023224, + 0.4000000059604645, + 0.800000011920929 + ], + "alpha": 0.75, + "thickness": 2.5, + "modifierCounts": { + "alpha": 1, + "color": 1, + "geometry": 2, + "thickness": 1 + } + } + ], + "second": [ + { + "id": "line-style:WebGapLineStyle", + "name": "WebGapLineStyle", + "color": [ + 0.20000000298023224, + 0.4000000059604645, + 0.800000011920929 + ], + "alpha": 0.75, + "thickness": 2.5, + "modifierCounts": { + "alpha": 1, + "color": 1, + "geometry": 2, + "thickness": 1 + } + } + ], + "saveReopenExact": true, + "deterministicExact": true, + "savedSha256": "997d904b79d5c1578eb2c51d7abd9d02129cd2385f39a2a7b33424ba2780e0aa", + "malformed": { + "code": "BLEND_READ_FAILED", + "message": "Input is not an uncompressed, gzip, or zstd Blender file" + } +} diff --git a/tests/golden/WBV2-P1159-001/manifest.json b/tests/golden/WBV2-P1159-001/manifest.json new file mode 100644 index 000000000..f6cdfd8f1 --- /dev/null +++ b/tests/golden/WBV2-P1159-001/manifest.json @@ -0,0 +1,99 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P1159-001", + "parentTask": "WBV2-P1159-000", + "operation": "MODULE_FUNCTION_EXECUTION", + "taskClass": "MODULE", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "BLENDER_WEB_FUNCTION_MODULE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P1159-000/manifest.json", + "sha256": "38ce017a10e5f070f0ceed0d5c69632cd9d047ed9ed1072db51509721d52d0fe" + }, + "source1": { + "path": "blender-5.2.0/source/blender/makesrna/intern/rna_main_api.cc", + "sha256": "98ba7298f114e7b296051a16fda41de5b4b9d3ea69f2cfdfae3723bd3de441ff" + }, + "source2": { + "path": "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "sha256": "80d9fa286b7952ddecb39137a033cd1320f6747086dbeb41fe009ad7b0186f28" + }, + "source3": { + "path": "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "sha256": "80d9fa286b7952ddecb39137a033cd1320f6747086dbeb41fe009ad7b0186f28" + }, + "source4": { + "path": "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "sha256": "80d9fa286b7952ddecb39137a033cd1320f6747086dbeb41fe009ad7b0186f28" + }, + "source5": { + "path": "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "sha256": "80d9fa286b7952ddecb39137a033cd1320f6747086dbeb41fe009ad7b0186f28" + }, + "source6": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "sha256": "f6fbd04315c48ad4dfbf109b91e5b350550d23c227e5c11a71a58f09e923c990" + }, + "source7": { + "path": "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "sha256": "a84afe76578bc78dfb3727abfea33c32b10417bf19a411053d21db9aef1e23fe" + }, + "source8": { + "path": "tests/files/web/line_style_modifier_batch_scene.blend", + "sha256": "997d904b79d5c1578eb2c51d7abd9d02129cd2385f39a2a7b33424ba2780e0aa" + }, + "source9": { + "path": "web/app/src/vendor/blender/web_engine.wasm", + "sha256": "32bc36aba563fe1ed0fb5d0292ca8a3ada1eecd6d45e38d9dcde565f02a312fe" + }, + "evidence1": { + "path": "tests/golden/WBV2-P1159-001/line-style-reader-production.json", + "sha256": "ee652cdc845647206b3856d97c781f623ef7905ffe54c29b366f2a8c8ce30535" + }, + "moduleReceipt": { + "path": "tests/golden/WBV2-P1159-001/module-receipt.json", + "sha256": "55be2535089c0748899a72fb0984323f63251844b1dc3149837c913ccb7f94f5" + }, + "status": { + "path": "docs/status/WBV2-P1159-001.md", + "sha256": "c0a66b526016b4faa22db75c4bdc744acd633fdc7000efb1424c6458ce29b1e9" + }, + "log": { + "path": "tests/golden/WBV2-P1159-001/module-run.log", + "sha256": "9683b7678c24d7a3f33d66c2eb0edf1db649f29cdf067ad6caa43a92033fc4e4" + }, + "plan": { + "path": "tests/golden/WBV2-P1159-000/module-execution-plan.json", + "sha256": "51f559bc3900fdcaf9e8639505a160fad9f83d7239ae0ed26258dea439f40235" + }, + "taskContext": { + "path": "tests/golden/WBV2-P1159-001/task-context.json", + "sha256": "9d321c8684896b3f9e45f7290b364c8c66d63f7147838c4fa9221da3f3794170" + } + }, + "assertions": { + "moduleId": "LINE_STYLE_COLLECTION_READER_BATCH", + "sourceBacked": true, + "positiveCases": 2, + "negativeCases": 3, + "recoveryCases": 3, + "commandCount": 4, + "reusedReceiptCount": 1, + "sourceUnchanged": true, + "fullFamilyParity": false, + "dynamicInventoryPath": "tests/golden/WBV2/dynamic-inventory.json", + "dynamicSourceTreeSha256": "600cb3dd441f09d9655b740735fbf8fa49ad6c14d308c68d59a29f9c338e4202", + "dynamicUnitCount": 3745, + "dynamicVerifiedUnits": 478, + "dynamicUnverifiedUnits": 3267, + "planningEstimate": 5200, + "historicalInventoryTotal": 6900, + "historicalEffectiveCompleted": 290, + "historicalEffectivePending": 6609, + "historicalReproduction": false + }, + "nextTask": null +} diff --git a/tests/golden/WBV2-P1159-001/module-receipt.json b/tests/golden/WBV2-P1159-001/module-receipt.json new file mode 100644 index 000000000..953a849be --- /dev/null +++ b/tests/golden/WBV2-P1159-001/module-receipt.json @@ -0,0 +1,125 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P1159-001", + "operation": "MODULE_FUNCTION_EXECUTION", + "moduleId": "LINE_STYLE_COLLECTION_READER_BATCH", + "status": "PASS", + "source": { + "paths": [ + "blender-5.2.0/source/blender/makesrna/intern/rna_main_api.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "tests/files/web/line_style_modifier_batch_scene.blend", + "web/app/src/vendor/blender/web_engine.wasm" + ], + "before": { + "blender-5.2.0/source/blender/makesrna/intern/rna_main_api.cc": "98ba7298f114e7b296051a16fda41de5b4b9d3ea69f2cfdfae3723bd3de441ff", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc": "80d9fa286b7952ddecb39137a033cd1320f6747086dbeb41fe009ad7b0186f28", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp": "f6fbd04315c48ad4dfbf109b91e5b350550d23c227e5c11a71a58f09e923c990", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts": "a84afe76578bc78dfb3727abfea33c32b10417bf19a411053d21db9aef1e23fe", + "tests/files/web/line_style_modifier_batch_scene.blend": "997d904b79d5c1578eb2c51d7abd9d02129cd2385f39a2a7b33424ba2780e0aa", + "web/app/src/vendor/blender/web_engine.wasm": "32bc36aba563fe1ed0fb5d0292ca8a3ada1eecd6d45e38d9dcde565f02a312fe" + }, + "after": { + "blender-5.2.0/source/blender/makesrna/intern/rna_main_api.cc": "98ba7298f114e7b296051a16fda41de5b4b9d3ea69f2cfdfae3723bd3de441ff", + "blender-5.2.0/source/blender/makesrna/intern/rna_linestyle.cc": "80d9fa286b7952ddecb39137a033cd1320f6747086dbeb41fe009ad7b0186f28", + "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp": "f6fbd04315c48ad4dfbf109b91e5b350550d23c227e5c11a71a58f09e923c990", + "web/tests/e2e/wbv2-line-style-reader-production.spec.ts": "a84afe76578bc78dfb3727abfea33c32b10417bf19a411053d21db9aef1e23fe", + "tests/files/web/line_style_modifier_batch_scene.blend": "997d904b79d5c1578eb2c51d7abd9d02129cd2385f39a2a7b33424ba2780e0aa", + "web/app/src/vendor/blender/web_engine.wasm": "32bc36aba563fe1ed0fb5d0292ca8a3ada1eecd6d45e38d9dcde565f02a312fe" + }, + "unchanged": true + }, + "reusedReceipts": [ + { + "manifest": "tests/golden/WBV2-P1107-000/manifest.json", + "report": "tests/golden/WBV2-P1107-000/module-receipt.json", + "manifestSha256": "a53ebdc52db5dcf27d44e938e5551f1ee2adae8e46c3fe8661604ee6b1000f8c", + "reportSha256": "6dd419799e1a4b9251328d9496f2459d148cd89118740a06b0ee6ffb78e0b1d2" + } + ], + "cases": { + "positive": [ + "shared RNA metadata is preserved", + "save/reopen preserves the batch metadata" + ], + "negative": [ + "malformed blend is rejected without Main mutation", + "unsupported batch data fails closed", + "non-finite metadata is not synthesized" + ], + "recovery": [ + "save/reopen", + "worker termination", + "deterministic second read" + ] + }, + "commands": [ + { + "command": "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm", + "exitCode": 0, + "durationMs": 149 + }, + { + "command": "npm --prefix web run typecheck", + "exitCode": 0, + "durationMs": 3283 + }, + { + "command": "npm --prefix web run build", + "exitCode": 0, + "durationMs": 3856 + }, + { + "command": "WBV2_BATCH_TASK=WBV2-P1159-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1159-001/line-style-reader-production.json WBV2_BATCH_FIXTURE=tests/files/web/line_style_modifier_batch_scene.blend WBV2_BATCH_TYPES='[]' WBV2_BATCH_UNITS='[\"rna-struct:BlendDataLineStyles\",\"rna-struct:LineStyleColorModifiers\",\"rna-struct:LineStyleAlphaModifiers\",\"rna-struct:LineStyleThicknessModifiers\",\"rna-struct:LineStyleGeometryModifiers\"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-line-style-reader-production.spec.ts", + "exitCode": 0, + "durationMs": 2964 + } + ], + "verification": { + "required": [ + "sourceHash", + "wasmBuild", + "positiveMainMutation", + "negativeNoMutation", + "undoRedo", + "saveReopen", + "aggregateManifest" + ], + "chromiumOnly": true, + "fullFamilyParity": false + }, + "efficiency": { + "existingEvidenceReused": false, + "skippedCommands": 0, + "totalDurationMs": 10252, + "reusePolicy": "hash_bound_receipt" + }, + "inventory": { + "historical": { + "path": "tests/golden/WBV2-P0-002/parity-map.json", + "sha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8", + "total": 6900, + "legacyCompleted": 281, + "legacyPending": 6618, + "effectiveCompleted": 290, + "effectivePending": 6609, + "mutation": "forbidden_by_module_execution" + }, + "dynamic": { + "path": "tests/golden/WBV2/dynamic-inventory.json", + "sha256": "a202315957c2a8eb2a812408d3fc9cdf132f8a18c7ab61854f0c6ba56798bee1", + "sourceTreeSha256": "600cb3dd441f09d9655b740735fbf8fa49ad6c14d308c68d59a29f9c338e4202", + "unitCount": 3745, + "planningEstimate": 5200, + "hardTarget": false, + "verifiedUnits": 478, + "unverifiedUnits": 3267 + } + }, + "nextTask": null +} diff --git a/tests/golden/WBV2-P1159-001/module-run.log b/tests/golden/WBV2-P1159-001/module-run.log new file mode 100644 index 000000000..1e22a44a3 --- /dev/null +++ b/tests/golden/WBV2-P1159-001/module-run.log @@ -0,0 +1,49 @@ +> source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm +ninja: no work to do. + +> npm --prefix web run typecheck + +> blender-web-editor@0.1.0-rc.1 typecheck +> tsc -p tsconfig.json --noEmit + + +> npm --prefix web run build + +> blender-web-editor@0.1.0-rc.1 build +> tsc -p tsconfig.json && vite build --config app/vite.config.ts + +vite v8.2.0 building client environment for production... + transforming...✓ 102 modules transformed. +rendering chunks... +computing gzip size... +dist/index.html 0.46 kB │ gzip: 0.30 kB +dist/assets/storage.worker-D9TqXsGS.js 66.59 kB +dist/assets/web-engine.worker-BfTMiTY1.js 362.11 kB +dist/assets/viewport-render.worker-BKnJyAEz.js 634.08 kB +dist/assets/web_engine-CjnzAIfx.wasm 16,238.37 kB │ gzip: 3,856.73 kB +dist/assets/index-BgTbQCE2.css 15.35 kB │ gzip: 3.91 kB +dist/assets/index-C3AJuKSc.js 1,190.30 kB │ gzip: 316.69 kB + +✓ built in 454ms +[plugin rolldown:vite-resolve] Module "module" has been externalized for browser compatibility, imported by "/home/mes123456/workinf_Blender_Wasm/web/app/src/vendor/blender/web_engine.js". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details. +[plugin builtin:vite-reporter] +(!) Some chunks are larger than 500 kB after minification. Consider: +- Using dynamic import() to code-split the application +- Use build.rolldownOptions.output.codeSplitting to improve chunking: https://rolldown.rs/reference/OutputOptions.codeSplitting +- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit. + +> WBV2_BATCH_TASK=WBV2-P1159-001 WBV2_BATCH_PRODUCTION=tests/golden/WBV2-P1159-001/line-style-reader-production.json WBV2_BATCH_FIXTURE=tests/files/web/line_style_modifier_batch_scene.blend WBV2_BATCH_TYPES='[]' WBV2_BATCH_UNITS='["rna-struct:BlendDataLineStyles","rna-struct:LineStyleColorModifiers","rna-struct:LineStyleAlphaModifiers","rna-struct:LineStyleThicknessModifiers","rna-struct:LineStyleGeometryModifiers"]' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-line-style-reader-production.spec.ts + +> blender-web-editor@0.1.0-rc.1 test:e2e +> playwright test --config playwright.config.ts --workers=1 tests/e2e/wbv2-line-style-reader-production.spec.ts + + +Running 1 test using 1 worker + + ✓ 1 tests/e2e/wbv2-line-style-reader-production.spec.ts:13:1 › line style reader preserves Blender Main style metadata (1.8s) + + 1 passed (2.6s) +[WebServer] (node:167535) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set. +[WebServer] (Use `node --trace-warnings ...` to show where the warning was created) +(node:167589) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set. +(Use `node --trace-warnings ...` to show where the warning was created) diff --git a/tests/golden/WBV2-P1159-001/task-context.json b/tests/golden/WBV2-P1159-001/task-context.json new file mode 100644 index 000000000..4ddc50937 --- /dev/null +++ b/tests/golden/WBV2-P1159-001/task-context.json @@ -0,0 +1,187 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P1159-001", + "parentTask": "WBV2-P1159-000", + "status": "in_progress", + "goal": "以一个共享 Blender Main reader、WASM build、Worker 路由和 Chromium receipt 批量验证 RNA-only reader units 的真实 modifier/RNA 元数据。", + "scope": { + "gap": "capability:LINE_STYLE_COLLECTION_READER_BATCH", + "ownerFamily": "DRAWING", + "implementationClass": "LOCAL_EXACT" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P1159-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 1918, + "contextRemainingTokens": 477 + }, + "source": { + "bytes": 7986, + "tokens": 1999 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/modifiers/intern/", + "bytes": 10155, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/makesrna/intern/rna_modifier.cc", + "bytes": 521651, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", + "bytes": 313993, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/files/web/line_style_modifier_batch_scene.blend", + "bytes": 86107, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/tests/e2e/wbv2-line-style-reader-production.spec.ts", + "bytes": 4028, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P1159-001/module-receipt.json", + "bytes": null, + "reason": "MISSING_PATH" + }, + { + "path": "tests/golden/WBV2-P1159-001/modifier-reader-batch-production.json", + "bytes": null, + "reason": "MISSING_PATH" + }, + { + "path": "tests/golden/WBV2-P1159-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P1159-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "source and protocol hashes are bound", + "every selected Main reader type is proven", + "negative no-mutation and recovery are proven", + "Chromium and save/reopen evidence are exact" + ], + "nextTask": null, + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P1159-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P1159-000/manifest.json", + "parentStatus": "docs/status/WBV2-P1159-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P1159-001.md", + "tests/golden/WBV2-P1159-000/manifest.json", + "docs/status/WBV2-P1159-000.md" + ], + "machineOnly": [ + "tests/golden/WBV2/task-index.json", + "tests/golden/M15-03A/task-catalog.jsonl" + ], + "optionalByNeed": [ + "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "任务卡列出的精确协议/生产路径", + "任务卡明确命名的长期计划小节" + ], + "forbiddenByDefault": [ + "完整 CURRENT_EXECUTION_PLAN.md", + "完整 PROJECT_STATUS_AND_NEXT_WORK.md", + "全部 docs/status/*.md", + "完整 parity/WBS 计划", + "README 历史和 test-results/" + ] + }, + "parent": { + "manifest": { + "schemaVersion": 1, + "task": "WBV2-P1159-000", + "parentTask": "WBV2-P1158-001", + "status": "done", + "nextTask": "WBV2-P1159-001", + "artifactCount": 4 + }, + "statusSummary": [ + "# WBV2-P1159-000 status", + "- task: `WBV2-P1159-000`; parent: `WBV2-P1158-001`; status: `done`", + "- taskClass: `QUEUE_ENABLEMENT`; no modifier-family parity completion claimed", + "- source-backed batch authorized: `LINE_STYLE_COLLECTION_READER_BATCH` (5 units)", + "- dynamic inventory: `3745` units; verified `473`; unverified `3272`; bound delta `0`", + "- nextTask: `WBV2-P1159-001`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 2201, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 46, + "taskTokens": 551 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 4030, + "lines": 58, + "tokens": 1008 + }, + { + "path": "docs/tasks/WBV2-P1159-001.md", + "bytes": 2201, + "lines": 46, + "tokens": 551 + }, + { + "path": "tests/golden/WBV2-P1159-000/manifest.json", + "bytes": 1389, + "lines": 43, + "tokens": 348 + }, + { + "path": "docs/status/WBV2-P1159-000.md", + "bytes": 366, + "lines": 8, + "tokens": 92 + } + ], + "sourceTokens": 1999, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1999, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 3023, + "serializedContextTokens": 655, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2/task-catalog.jsonl b/tests/golden/WBV2/task-catalog.jsonl index 2ded03008..7393ee7e6 100644 --- a/tests/golden/WBV2/task-catalog.jsonl +++ b/tests/golden/WBV2/task-catalog.jsonl @@ -95,3 +95,5 @@ {"id":"WBV2-P1157-001","gapId":"SHAPE_KEY_POINT_READER_BATCH","ownerFamily":"ANIMATION","sourceTask":"1157","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["source and protocol hashes are bound","every selected Main reader type is proven","negative no-mutation and recovery are proven","Chromium and save/reopen evidence are exact"]} {"id":"WBV2-P1158-000","gapId":"workflow:authorize_modifier_reader_batch","ownerFamily":"PROGRAM","sourceTask":"1158","state":"completed","targetImplementationClass":"QUEUE_ONLY","exitCriteria":["prior evidence remains hash-bound","batch source mapping is explicit","inventory remains source-derived"]} {"id":"WBV2-P1158-001","gapId":"LINE_STYLE_READER_BATCH","ownerFamily":"DRAWING","sourceTask":"1158","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["source and protocol hashes are bound","every selected Main reader type is proven","negative no-mutation and recovery are proven","Chromium and save/reopen evidence are exact"]} +{"id":"WBV2-P1159-000","gapId":"workflow:authorize_modifier_reader_batch","ownerFamily":"PROGRAM","sourceTask":"1159","state":"completed","targetImplementationClass":"QUEUE_ONLY","exitCriteria":["prior evidence remains hash-bound","batch source mapping is explicit","inventory remains source-derived"]} +{"id":"WBV2-P1159-001","gapId":"LINE_STYLE_COLLECTION_READER_BATCH","ownerFamily":"DRAWING","sourceTask":"1159","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["source and protocol hashes are bound","every selected Main reader type is proven","negative no-mutation and recovery are proven","Chromium and save/reopen evidence are exact"]} diff --git a/tests/golden/WBV2/task-index.json b/tests/golden/WBV2/task-index.json index 5553bd273..40685e43b 100644 --- a/tests/golden/WBV2/task-index.json +++ b/tests/golden/WBV2/task-index.json @@ -1 +1 @@ -{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P1158-000/module-execution-plan.json","sha256":"f6b520eddcd5f399ae9244524933b37d62a3f83047d10f74fd076801227c4cd0"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"b412de45c047f1f2a0563adcc9bcbe4492ae6deaba1b09dc7ce4c209896171ea"},"taskCount":97,"activeTask":null,"entries":{"WBV2-P1096-000":{"line":0,"offset":0,"length":267,"previous":"WBV2-P1095-003","next":"WBV2-P1100-000"},"WBV2-P1100-000":{"line":1,"offset":267,"length":300,"previous":"WBV2-P1096-000","next":"WBV2-P1100-001"},"WBV2-P1100-001":{"line":2,"offset":567,"length":375,"previous":"WBV2-P1100-000","next":"WBV2-P1100-002"},"WBV2-P1100-002":{"line":3,"offset":942,"length":377,"previous":"WBV2-P1100-001","next":"WBV2-P1100-003"},"WBV2-P1100-003":{"line":4,"offset":1319,"length":386,"previous":"WBV2-P1100-002","next":"WBV2-P1101-000"},"WBV2-P1101-000":{"line":5,"offset":1705,"length":374,"previous":"WBV2-P1100-003","next":"WBV2-P1101-001"},"WBV2-P1101-001":{"line":6,"offset":2079,"length":382,"previous":"WBV2-P1101-000","next":"WBV2-P1101-002"},"WBV2-P1101-002":{"line":7,"offset":2461,"length":363,"previous":"WBV2-P1101-001","next":"WBV2-P1101-003"},"WBV2-P1101-003":{"line":8,"offset":2824,"length":374,"previous":"WBV2-P1101-002","next":"WBV2-P1102-000"},"WBV2-P1102-000":{"line":9,"offset":3198,"length":365,"previous":"WBV2-P1101-003","next":"WBV2-P1102-001"},"WBV2-P1102-001":{"line":10,"offset":3563,"length":371,"previous":"WBV2-P1102-000","next":"WBV2-P1103-000"},"WBV2-P1103-000":{"line":11,"offset":3934,"length":373,"previous":"WBV2-P1102-001","next":"WBV2-P1104-000"},"WBV2-P1104-000":{"line":12,"offset":4307,"length":389,"previous":"WBV2-P1103-000","next":"WBV2-P1105-000"},"WBV2-P1105-000":{"line":13,"offset":4696,"length":426,"previous":"WBV2-P1104-000","next":"WBV2-P1106-000"},"WBV2-P1106-000":{"line":14,"offset":5122,"length":366,"previous":"WBV2-P1105-000","next":"WBV2-P1107-000"},"WBV2-P1107-000":{"line":15,"offset":5488,"length":373,"previous":"WBV2-P1106-000","next":"WBV2-P1108-000"},"WBV2-P1108-000":{"line":16,"offset":5861,"length":385,"previous":"WBV2-P1107-000","next":"WBV2-P1109-000"},"WBV2-P1109-000":{"line":17,"offset":6246,"length":397,"previous":"WBV2-P1108-000","next":"WBV2-P1110-000"},"WBV2-P1110-000":{"line":18,"offset":6643,"length":394,"previous":"WBV2-P1109-000","next":"WBV2-P1111-000"},"WBV2-P1111-000":{"line":19,"offset":7037,"length":384,"previous":"WBV2-P1110-000","next":"WBV2-P1112-000"},"WBV2-P1112-000":{"line":20,"offset":7421,"length":397,"previous":"WBV2-P1111-000","next":"WBV2-P1113-000"},"WBV2-P1113-000":{"line":21,"offset":7818,"length":393,"previous":"WBV2-P1112-000","next":"WBV2-P1114-000"},"WBV2-P1114-000":{"line":22,"offset":8211,"length":384,"previous":"WBV2-P1113-000","next":"WBV2-P1115-000"},"WBV2-P1115-000":{"line":23,"offset":8595,"length":388,"previous":"WBV2-P1114-000","next":"WBV2-P1116-000"},"WBV2-P1116-000":{"line":24,"offset":8983,"length":388,"previous":"WBV2-P1115-000","next":"WBV2-P1117-000"},"WBV2-P1117-000":{"line":25,"offset":9371,"length":413,"previous":"WBV2-P1116-000","next":"WBV2-P1118-000"},"WBV2-P1118-000":{"line":26,"offset":9784,"length":409,"previous":"WBV2-P1117-000","next":"WBV2-P1119-000"},"WBV2-P1119-000":{"line":27,"offset":10193,"length":379,"previous":"WBV2-P1118-000","next":"WBV2-P1120-000"},"WBV2-P1120-000":{"line":28,"offset":10572,"length":392,"previous":"WBV2-P1119-000","next":"WBV2-P1121-000"},"WBV2-P1121-000":{"line":29,"offset":10964,"length":375,"previous":"WBV2-P1120-000","next":"WBV2-P1122-000"},"WBV2-P1122-000":{"line":30,"offset":11339,"length":385,"previous":"WBV2-P1121-000","next":"WBV2-P1123-000"},"WBV2-P1123-000":{"line":31,"offset":11724,"length":385,"previous":"WBV2-P1122-000","next":"WBV2-P1124-000"},"WBV2-P1124-000":{"line":32,"offset":12109,"length":431,"previous":"WBV2-P1123-000","next":"WBV2-P1125-000"},"WBV2-P1125-000":{"line":33,"offset":12540,"length":406,"previous":"WBV2-P1124-000","next":"WBV2-P1126-000"},"WBV2-P1126-000":{"line":34,"offset":12946,"length":397,"previous":"WBV2-P1125-000","next":"WBV2-P1127-000"},"WBV2-P1127-000":{"line":35,"offset":13343,"length":406,"previous":"WBV2-P1126-000","next":"WBV2-P1128-000"},"WBV2-P1128-000":{"line":36,"offset":13749,"length":406,"previous":"WBV2-P1127-000","next":"WBV2-P1129-000"},"WBV2-P1129-000":{"line":37,"offset":14155,"length":331,"previous":"WBV2-P1128-000","next":"WBV2-P1129-001"},"WBV2-P1129-001":{"line":38,"offset":14486,"length":393,"previous":"WBV2-P1129-000","next":"WBV2-P1130-000"},"WBV2-P1130-000":{"line":39,"offset":14879,"length":348,"previous":"WBV2-P1129-001","next":"WBV2-P1130-001"},"WBV2-P1130-001":{"line":40,"offset":15227,"length":387,"previous":"WBV2-P1130-000","next":"WBV2-P1131-000"},"WBV2-P1131-000":{"line":41,"offset":15614,"length":349,"previous":"WBV2-P1130-001","next":"WBV2-P1131-001"},"WBV2-P1131-001":{"line":42,"offset":15963,"length":383,"previous":"WBV2-P1131-000","next":"WBV2-P1132-000"},"WBV2-P1132-000":{"line":43,"offset":16346,"length":345,"previous":"WBV2-P1131-001","next":"WBV2-P1132-001"},"WBV2-P1132-001":{"line":44,"offset":16691,"length":380,"previous":"WBV2-P1132-000","next":"WBV2-P1133-000"},"WBV2-P1133-000":{"line":45,"offset":17071,"length":346,"previous":"WBV2-P1132-001","next":"WBV2-P1133-001"},"WBV2-P1133-001":{"line":46,"offset":17417,"length":387,"previous":"WBV2-P1133-000","next":"WBV2-P1134-000"},"WBV2-P1134-000":{"line":47,"offset":17804,"length":353,"previous":"WBV2-P1133-001","next":"WBV2-P1134-001"},"WBV2-P1134-001":{"line":48,"offset":18157,"length":392,"previous":"WBV2-P1134-000","next":"WBV2-P1135-000"},"WBV2-P1135-000":{"line":49,"offset":18549,"length":339,"previous":"WBV2-P1134-001","next":"WBV2-P1135-001"},"WBV2-P1135-001":{"line":50,"offset":18888,"length":385,"previous":"WBV2-P1135-000","next":"WBV2-P1136-000"},"WBV2-P1136-000":{"line":51,"offset":19273,"length":349,"previous":"WBV2-P1135-001","next":"WBV2-P1136-001"},"WBV2-P1136-001":{"line":52,"offset":19622,"length":391,"previous":"WBV2-P1136-000","next":"WBV2-P1137-000"},"WBV2-P1137-000":{"line":53,"offset":20013,"length":354,"previous":"WBV2-P1136-001","next":"WBV2-P1137-001"},"WBV2-P1137-001":{"line":54,"offset":20367,"length":393,"previous":"WBV2-P1137-000","next":"WBV2-P1138-000"},"WBV2-P1138-000":{"line":55,"offset":20760,"length":340,"previous":"WBV2-P1137-001","next":"WBV2-P1138-001"},"WBV2-P1138-001":{"line":56,"offset":21100,"length":388,"previous":"WBV2-P1138-000","next":"WBV2-P1139-000"},"WBV2-P1139-000":{"line":57,"offset":21488,"length":344,"previous":"WBV2-P1138-001","next":"WBV2-P1139-001"},"WBV2-P1139-001":{"line":58,"offset":21832,"length":393,"previous":"WBV2-P1139-000","next":"WBV2-P1140-000"},"WBV2-P1140-000":{"line":59,"offset":22225,"length":362,"previous":"WBV2-P1139-001","next":"WBV2-P1140-001"},"WBV2-P1140-001":{"line":60,"offset":22587,"length":382,"previous":"WBV2-P1140-000","next":"WBV2-P1141-000"},"WBV2-P1141-000":{"line":61,"offset":22969,"length":368,"previous":"WBV2-P1140-001","next":"WBV2-P1141-001"},"WBV2-P1141-001":{"line":62,"offset":23337,"length":389,"previous":"WBV2-P1141-000","next":"WBV2-P1142-000"},"WBV2-P1142-000":{"line":63,"offset":23726,"length":364,"previous":"WBV2-P1141-001","next":"WBV2-P1142-001"},"WBV2-P1142-001":{"line":64,"offset":24090,"length":383,"previous":"WBV2-P1142-000","next":"WBV2-P1143-000"},"WBV2-P1143-000":{"line":65,"offset":24473,"length":369,"previous":"WBV2-P1142-001","next":"WBV2-P1143-001"},"WBV2-P1143-001":{"line":66,"offset":24842,"length":385,"previous":"WBV2-P1143-000","next":"WBV2-P1144-000"},"WBV2-P1144-000":{"line":67,"offset":25227,"length":351,"previous":"WBV2-P1143-001","next":"WBV2-P1144-001"},"WBV2-P1144-001":{"line":68,"offset":25578,"length":376,"previous":"WBV2-P1144-000","next":"WBV2-P1145-000"},"WBV2-P1145-000":{"line":69,"offset":25954,"length":371,"previous":"WBV2-P1144-001","next":"WBV2-P1145-001"},"WBV2-P1145-001":{"line":70,"offset":26325,"length":386,"previous":"WBV2-P1145-000","next":"WBV2-P1146-000"},"WBV2-P1146-000":{"line":71,"offset":26711,"length":303,"previous":"WBV2-P1145-001","next":"WBV2-P1146-001"},"WBV2-P1146-001":{"line":72,"offset":27014,"length":356,"previous":"WBV2-P1146-000","next":"WBV2-P1147-000"},"WBV2-P1147-000":{"line":73,"offset":27370,"length":303,"previous":"WBV2-P1146-001","next":"WBV2-P1147-001"},"WBV2-P1147-001":{"line":74,"offset":27673,"length":360,"previous":"WBV2-P1147-000","next":"WBV2-P1148-000"},"WBV2-P1148-000":{"line":75,"offset":28033,"length":303,"previous":"WBV2-P1147-001","next":"WBV2-P1148-001"},"WBV2-P1148-001":{"line":76,"offset":28336,"length":362,"previous":"WBV2-P1148-000","next":"WBV2-P1149-000"},"WBV2-P1149-000":{"line":77,"offset":28698,"length":303,"previous":"WBV2-P1148-001","next":"WBV2-P1149-001"},"WBV2-P1149-001":{"line":78,"offset":29001,"length":361,"previous":"WBV2-P1149-000","next":"WBV2-P1150-000"},"WBV2-P1150-000":{"line":79,"offset":29362,"length":303,"previous":"WBV2-P1149-001","next":"WBV2-P1150-001"},"WBV2-P1150-001":{"line":80,"offset":29665,"length":361,"previous":"WBV2-P1150-000","next":"WBV2-P1151-000"},"WBV2-P1151-000":{"line":81,"offset":30026,"length":303,"previous":"WBV2-P1150-001","next":"WBV2-P1151-001"},"WBV2-P1151-001":{"line":82,"offset":30329,"length":369,"previous":"WBV2-P1151-000","next":"WBV2-P1152-000"},"WBV2-P1152-000":{"line":83,"offset":30698,"length":303,"previous":"WBV2-P1151-001","next":"WBV2-P1152-001"},"WBV2-P1152-001":{"line":84,"offset":31001,"length":360,"previous":"WBV2-P1152-000","next":"WBV2-P1153-000"},"WBV2-P1153-000":{"line":85,"offset":31361,"length":303,"previous":"WBV2-P1152-001","next":"WBV2-P1153-001"},"WBV2-P1153-001":{"line":86,"offset":31664,"length":367,"previous":"WBV2-P1153-000","next":"WBV2-P1154-000"},"WBV2-P1154-000":{"line":87,"offset":32031,"length":303,"previous":"WBV2-P1153-001","next":"WBV2-P1154-001"},"WBV2-P1154-001":{"line":88,"offset":32334,"length":365,"previous":"WBV2-P1154-000","next":"WBV2-P1155-000"},"WBV2-P1155-000":{"line":89,"offset":32699,"length":303,"previous":"WBV2-P1154-001","next":"WBV2-P1155-001"},"WBV2-P1155-001":{"line":90,"offset":33002,"length":360,"previous":"WBV2-P1155-000","next":"WBV2-P1156-000"},"WBV2-P1156-000":{"line":91,"offset":33362,"length":303,"previous":"WBV2-P1155-001","next":"WBV2-P1156-001"},"WBV2-P1156-001":{"line":92,"offset":33665,"length":365,"previous":"WBV2-P1156-000","next":"WBV2-P1157-000"},"WBV2-P1157-000":{"line":93,"offset":34030,"length":303,"previous":"WBV2-P1156-001","next":"WBV2-P1157-001"},"WBV2-P1157-001":{"line":94,"offset":34333,"length":364,"previous":"WBV2-P1157-000","next":"WBV2-P1158-000"},"WBV2-P1158-000":{"line":95,"offset":34697,"length":303,"previous":"WBV2-P1157-001","next":"WBV2-P1158-001"},"WBV2-P1158-001":{"line":96,"offset":35000,"length":357,"previous":"WBV2-P1158-000","next":null}}} +{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P1159-000/module-execution-plan.json","sha256":"51f559bc3900fdcaf9e8639505a160fad9f83d7239ae0ed26258dea439f40235"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"301616559af31d0e983743ceeda532d5f46e28d52319772dce8fd03744b86e3c"},"taskCount":99,"activeTask":null,"entries":{"WBV2-P1096-000":{"line":0,"offset":0,"length":267,"previous":"WBV2-P1095-003","next":"WBV2-P1100-000"},"WBV2-P1100-000":{"line":1,"offset":267,"length":300,"previous":"WBV2-P1096-000","next":"WBV2-P1100-001"},"WBV2-P1100-001":{"line":2,"offset":567,"length":375,"previous":"WBV2-P1100-000","next":"WBV2-P1100-002"},"WBV2-P1100-002":{"line":3,"offset":942,"length":377,"previous":"WBV2-P1100-001","next":"WBV2-P1100-003"},"WBV2-P1100-003":{"line":4,"offset":1319,"length":386,"previous":"WBV2-P1100-002","next":"WBV2-P1101-000"},"WBV2-P1101-000":{"line":5,"offset":1705,"length":374,"previous":"WBV2-P1100-003","next":"WBV2-P1101-001"},"WBV2-P1101-001":{"line":6,"offset":2079,"length":382,"previous":"WBV2-P1101-000","next":"WBV2-P1101-002"},"WBV2-P1101-002":{"line":7,"offset":2461,"length":363,"previous":"WBV2-P1101-001","next":"WBV2-P1101-003"},"WBV2-P1101-003":{"line":8,"offset":2824,"length":374,"previous":"WBV2-P1101-002","next":"WBV2-P1102-000"},"WBV2-P1102-000":{"line":9,"offset":3198,"length":365,"previous":"WBV2-P1101-003","next":"WBV2-P1102-001"},"WBV2-P1102-001":{"line":10,"offset":3563,"length":371,"previous":"WBV2-P1102-000","next":"WBV2-P1103-000"},"WBV2-P1103-000":{"line":11,"offset":3934,"length":373,"previous":"WBV2-P1102-001","next":"WBV2-P1104-000"},"WBV2-P1104-000":{"line":12,"offset":4307,"length":389,"previous":"WBV2-P1103-000","next":"WBV2-P1105-000"},"WBV2-P1105-000":{"line":13,"offset":4696,"length":426,"previous":"WBV2-P1104-000","next":"WBV2-P1106-000"},"WBV2-P1106-000":{"line":14,"offset":5122,"length":366,"previous":"WBV2-P1105-000","next":"WBV2-P1107-000"},"WBV2-P1107-000":{"line":15,"offset":5488,"length":373,"previous":"WBV2-P1106-000","next":"WBV2-P1108-000"},"WBV2-P1108-000":{"line":16,"offset":5861,"length":385,"previous":"WBV2-P1107-000","next":"WBV2-P1109-000"},"WBV2-P1109-000":{"line":17,"offset":6246,"length":397,"previous":"WBV2-P1108-000","next":"WBV2-P1110-000"},"WBV2-P1110-000":{"line":18,"offset":6643,"length":394,"previous":"WBV2-P1109-000","next":"WBV2-P1111-000"},"WBV2-P1111-000":{"line":19,"offset":7037,"length":384,"previous":"WBV2-P1110-000","next":"WBV2-P1112-000"},"WBV2-P1112-000":{"line":20,"offset":7421,"length":397,"previous":"WBV2-P1111-000","next":"WBV2-P1113-000"},"WBV2-P1113-000":{"line":21,"offset":7818,"length":393,"previous":"WBV2-P1112-000","next":"WBV2-P1114-000"},"WBV2-P1114-000":{"line":22,"offset":8211,"length":384,"previous":"WBV2-P1113-000","next":"WBV2-P1115-000"},"WBV2-P1115-000":{"line":23,"offset":8595,"length":388,"previous":"WBV2-P1114-000","next":"WBV2-P1116-000"},"WBV2-P1116-000":{"line":24,"offset":8983,"length":388,"previous":"WBV2-P1115-000","next":"WBV2-P1117-000"},"WBV2-P1117-000":{"line":25,"offset":9371,"length":413,"previous":"WBV2-P1116-000","next":"WBV2-P1118-000"},"WBV2-P1118-000":{"line":26,"offset":9784,"length":409,"previous":"WBV2-P1117-000","next":"WBV2-P1119-000"},"WBV2-P1119-000":{"line":27,"offset":10193,"length":379,"previous":"WBV2-P1118-000","next":"WBV2-P1120-000"},"WBV2-P1120-000":{"line":28,"offset":10572,"length":392,"previous":"WBV2-P1119-000","next":"WBV2-P1121-000"},"WBV2-P1121-000":{"line":29,"offset":10964,"length":375,"previous":"WBV2-P1120-000","next":"WBV2-P1122-000"},"WBV2-P1122-000":{"line":30,"offset":11339,"length":385,"previous":"WBV2-P1121-000","next":"WBV2-P1123-000"},"WBV2-P1123-000":{"line":31,"offset":11724,"length":385,"previous":"WBV2-P1122-000","next":"WBV2-P1124-000"},"WBV2-P1124-000":{"line":32,"offset":12109,"length":431,"previous":"WBV2-P1123-000","next":"WBV2-P1125-000"},"WBV2-P1125-000":{"line":33,"offset":12540,"length":406,"previous":"WBV2-P1124-000","next":"WBV2-P1126-000"},"WBV2-P1126-000":{"line":34,"offset":12946,"length":397,"previous":"WBV2-P1125-000","next":"WBV2-P1127-000"},"WBV2-P1127-000":{"line":35,"offset":13343,"length":406,"previous":"WBV2-P1126-000","next":"WBV2-P1128-000"},"WBV2-P1128-000":{"line":36,"offset":13749,"length":406,"previous":"WBV2-P1127-000","next":"WBV2-P1129-000"},"WBV2-P1129-000":{"line":37,"offset":14155,"length":331,"previous":"WBV2-P1128-000","next":"WBV2-P1129-001"},"WBV2-P1129-001":{"line":38,"offset":14486,"length":393,"previous":"WBV2-P1129-000","next":"WBV2-P1130-000"},"WBV2-P1130-000":{"line":39,"offset":14879,"length":348,"previous":"WBV2-P1129-001","next":"WBV2-P1130-001"},"WBV2-P1130-001":{"line":40,"offset":15227,"length":387,"previous":"WBV2-P1130-000","next":"WBV2-P1131-000"},"WBV2-P1131-000":{"line":41,"offset":15614,"length":349,"previous":"WBV2-P1130-001","next":"WBV2-P1131-001"},"WBV2-P1131-001":{"line":42,"offset":15963,"length":383,"previous":"WBV2-P1131-000","next":"WBV2-P1132-000"},"WBV2-P1132-000":{"line":43,"offset":16346,"length":345,"previous":"WBV2-P1131-001","next":"WBV2-P1132-001"},"WBV2-P1132-001":{"line":44,"offset":16691,"length":380,"previous":"WBV2-P1132-000","next":"WBV2-P1133-000"},"WBV2-P1133-000":{"line":45,"offset":17071,"length":346,"previous":"WBV2-P1132-001","next":"WBV2-P1133-001"},"WBV2-P1133-001":{"line":46,"offset":17417,"length":387,"previous":"WBV2-P1133-000","next":"WBV2-P1134-000"},"WBV2-P1134-000":{"line":47,"offset":17804,"length":353,"previous":"WBV2-P1133-001","next":"WBV2-P1134-001"},"WBV2-P1134-001":{"line":48,"offset":18157,"length":392,"previous":"WBV2-P1134-000","next":"WBV2-P1135-000"},"WBV2-P1135-000":{"line":49,"offset":18549,"length":339,"previous":"WBV2-P1134-001","next":"WBV2-P1135-001"},"WBV2-P1135-001":{"line":50,"offset":18888,"length":385,"previous":"WBV2-P1135-000","next":"WBV2-P1136-000"},"WBV2-P1136-000":{"line":51,"offset":19273,"length":349,"previous":"WBV2-P1135-001","next":"WBV2-P1136-001"},"WBV2-P1136-001":{"line":52,"offset":19622,"length":391,"previous":"WBV2-P1136-000","next":"WBV2-P1137-000"},"WBV2-P1137-000":{"line":53,"offset":20013,"length":354,"previous":"WBV2-P1136-001","next":"WBV2-P1137-001"},"WBV2-P1137-001":{"line":54,"offset":20367,"length":393,"previous":"WBV2-P1137-000","next":"WBV2-P1138-000"},"WBV2-P1138-000":{"line":55,"offset":20760,"length":340,"previous":"WBV2-P1137-001","next":"WBV2-P1138-001"},"WBV2-P1138-001":{"line":56,"offset":21100,"length":388,"previous":"WBV2-P1138-000","next":"WBV2-P1139-000"},"WBV2-P1139-000":{"line":57,"offset":21488,"length":344,"previous":"WBV2-P1138-001","next":"WBV2-P1139-001"},"WBV2-P1139-001":{"line":58,"offset":21832,"length":393,"previous":"WBV2-P1139-000","next":"WBV2-P1140-000"},"WBV2-P1140-000":{"line":59,"offset":22225,"length":362,"previous":"WBV2-P1139-001","next":"WBV2-P1140-001"},"WBV2-P1140-001":{"line":60,"offset":22587,"length":382,"previous":"WBV2-P1140-000","next":"WBV2-P1141-000"},"WBV2-P1141-000":{"line":61,"offset":22969,"length":368,"previous":"WBV2-P1140-001","next":"WBV2-P1141-001"},"WBV2-P1141-001":{"line":62,"offset":23337,"length":389,"previous":"WBV2-P1141-000","next":"WBV2-P1142-000"},"WBV2-P1142-000":{"line":63,"offset":23726,"length":364,"previous":"WBV2-P1141-001","next":"WBV2-P1142-001"},"WBV2-P1142-001":{"line":64,"offset":24090,"length":383,"previous":"WBV2-P1142-000","next":"WBV2-P1143-000"},"WBV2-P1143-000":{"line":65,"offset":24473,"length":369,"previous":"WBV2-P1142-001","next":"WBV2-P1143-001"},"WBV2-P1143-001":{"line":66,"offset":24842,"length":385,"previous":"WBV2-P1143-000","next":"WBV2-P1144-000"},"WBV2-P1144-000":{"line":67,"offset":25227,"length":351,"previous":"WBV2-P1143-001","next":"WBV2-P1144-001"},"WBV2-P1144-001":{"line":68,"offset":25578,"length":376,"previous":"WBV2-P1144-000","next":"WBV2-P1145-000"},"WBV2-P1145-000":{"line":69,"offset":25954,"length":371,"previous":"WBV2-P1144-001","next":"WBV2-P1145-001"},"WBV2-P1145-001":{"line":70,"offset":26325,"length":386,"previous":"WBV2-P1145-000","next":"WBV2-P1146-000"},"WBV2-P1146-000":{"line":71,"offset":26711,"length":303,"previous":"WBV2-P1145-001","next":"WBV2-P1146-001"},"WBV2-P1146-001":{"line":72,"offset":27014,"length":356,"previous":"WBV2-P1146-000","next":"WBV2-P1147-000"},"WBV2-P1147-000":{"line":73,"offset":27370,"length":303,"previous":"WBV2-P1146-001","next":"WBV2-P1147-001"},"WBV2-P1147-001":{"line":74,"offset":27673,"length":360,"previous":"WBV2-P1147-000","next":"WBV2-P1148-000"},"WBV2-P1148-000":{"line":75,"offset":28033,"length":303,"previous":"WBV2-P1147-001","next":"WBV2-P1148-001"},"WBV2-P1148-001":{"line":76,"offset":28336,"length":362,"previous":"WBV2-P1148-000","next":"WBV2-P1149-000"},"WBV2-P1149-000":{"line":77,"offset":28698,"length":303,"previous":"WBV2-P1148-001","next":"WBV2-P1149-001"},"WBV2-P1149-001":{"line":78,"offset":29001,"length":361,"previous":"WBV2-P1149-000","next":"WBV2-P1150-000"},"WBV2-P1150-000":{"line":79,"offset":29362,"length":303,"previous":"WBV2-P1149-001","next":"WBV2-P1150-001"},"WBV2-P1150-001":{"line":80,"offset":29665,"length":361,"previous":"WBV2-P1150-000","next":"WBV2-P1151-000"},"WBV2-P1151-000":{"line":81,"offset":30026,"length":303,"previous":"WBV2-P1150-001","next":"WBV2-P1151-001"},"WBV2-P1151-001":{"line":82,"offset":30329,"length":369,"previous":"WBV2-P1151-000","next":"WBV2-P1152-000"},"WBV2-P1152-000":{"line":83,"offset":30698,"length":303,"previous":"WBV2-P1151-001","next":"WBV2-P1152-001"},"WBV2-P1152-001":{"line":84,"offset":31001,"length":360,"previous":"WBV2-P1152-000","next":"WBV2-P1153-000"},"WBV2-P1153-000":{"line":85,"offset":31361,"length":303,"previous":"WBV2-P1152-001","next":"WBV2-P1153-001"},"WBV2-P1153-001":{"line":86,"offset":31664,"length":367,"previous":"WBV2-P1153-000","next":"WBV2-P1154-000"},"WBV2-P1154-000":{"line":87,"offset":32031,"length":303,"previous":"WBV2-P1153-001","next":"WBV2-P1154-001"},"WBV2-P1154-001":{"line":88,"offset":32334,"length":365,"previous":"WBV2-P1154-000","next":"WBV2-P1155-000"},"WBV2-P1155-000":{"line":89,"offset":32699,"length":303,"previous":"WBV2-P1154-001","next":"WBV2-P1155-001"},"WBV2-P1155-001":{"line":90,"offset":33002,"length":360,"previous":"WBV2-P1155-000","next":"WBV2-P1156-000"},"WBV2-P1156-000":{"line":91,"offset":33362,"length":303,"previous":"WBV2-P1155-001","next":"WBV2-P1156-001"},"WBV2-P1156-001":{"line":92,"offset":33665,"length":365,"previous":"WBV2-P1156-000","next":"WBV2-P1157-000"},"WBV2-P1157-000":{"line":93,"offset":34030,"length":303,"previous":"WBV2-P1156-001","next":"WBV2-P1157-001"},"WBV2-P1157-001":{"line":94,"offset":34333,"length":364,"previous":"WBV2-P1157-000","next":"WBV2-P1158-000"},"WBV2-P1158-000":{"line":95,"offset":34697,"length":303,"previous":"WBV2-P1157-001","next":"WBV2-P1158-001"},"WBV2-P1158-001":{"line":96,"offset":35000,"length":357,"previous":"WBV2-P1158-000","next":"WBV2-P1159-000"},"WBV2-P1159-000":{"line":97,"offset":35357,"length":303,"previous":"WBV2-P1158-001","next":"WBV2-P1159-001"},"WBV2-P1159-001":{"line":98,"offset":35660,"length":368,"previous":"WBV2-P1159-000","next":null}}} diff --git a/web/tests/e2e/wbv2-line-style-reader-production.spec.ts b/web/tests/e2e/wbv2-line-style-reader-production.spec.ts index b36417817..92f8d9ff9 100644 --- a/web/tests/e2e/wbv2-line-style-reader-production.spec.ts +++ b/web/tests/e2e/wbv2-line-style-reader-production.spec.ts @@ -5,7 +5,7 @@ import { expect, test } from "@playwright/test"; const root = path.resolve(import.meta.dirname, "../../.."); const task = process.env.WBV2_BATCH_TASK ?? "WBV2-P1158-001"; -const fixture = "tests/files/web/generated/M16-GAP-00008-datablock-FreestyleLineStyle.blend"; +const fixture = process.env.WBV2_BATCH_FIXTURE ?? "tests/files/web/generated/M16-GAP-00008-datablock-FreestyleLineStyle.blend"; const fixtureBytes = fs.readFileSync(path.join(root, fixture)); const fixtureSha256 = crypto.createHash("sha256").update(fixtureBytes).digest("hex"); const sourceUnits = JSON.parse(process.env.WBV2_BATCH_UNITS ?? '["rna-struct:FreestyleLineStyle","rna-struct:LineStyleModifier","rna-struct:LineStyleAlphaModifier","rna-struct:LineStyleColorModifier","rna-struct:LineStyleGeometryModifier","rna-struct:LineStyleThicknessModifier"]'); @@ -22,6 +22,7 @@ test("line style reader preserves Blender Main style metadata", async ({ page }) alpha: style.alpha, thickness: style.thickness, geometry: style.geometry, + modifierCounts: style.modifierCounts ?? style.modifiers ?? null, })); const client = new WebEngineClient({ timeoutMs: 60_000 }); const reopenedClient = new WebEngineClient({ timeoutMs: 60_000 }); @@ -71,6 +72,13 @@ test("line style reader preserves Blender Main style metadata", async ({ page }) expect(result.error).toBeUndefined(); expect(result.styleCount).toBeGreaterThan(0); + if (task.includes("COLLECTION")) { + const counts = result.before[0]?.modifierCounts ?? {}; + expect(counts.color).toBeGreaterThan(0); + expect(counts.alpha).toBeGreaterThan(0); + expect(counts.thickness).toBeGreaterThan(0); + expect(counts.geometry).toBeGreaterThan(0); + } expect(result.saveReopenExact).toBe(true); expect(result.deterministicExact).toBe(true); expect(result.malformed?.code).not.toBe("ACCEPTED_MALFORMED");