diff --git a/docs/EXECUTION_QUEUE.md b/docs/EXECUTION_QUEUE.md index 27f211397..63129c67f 100644 --- a/docs/EXECUTION_QUEUE.md +++ b/docs/EXECUTION_QUEUE.md @@ -13,9 +13,9 @@ | 字段 | 值 | | --- | --- | | 里程碑 | WBV2 capability workflow | -| 当前任务 | `WBV2-P10-003` | -| parent manifest | `tests/golden/WBV2-P10-002/manifest.json` | -| 任务卡 | [`tasks/WBV2-P10-003.md`](tasks/WBV2-P10-003.md) | +| 当前任务 | `WBV2-P11-004` | +| parent manifest | `tests/golden/WBV2-P11-003/manifest.json` | +| 任务卡 | [`tasks/WBV2-P11-004.md`](tasks/WBV2-P11-004.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-P10-003.md b/docs/status/WBV2-P10-003.md index cc116b8d7..4175937e1 100644 --- a/docs/status/WBV2-P10-003.md +++ b/docs/status/WBV2-P10-003.md @@ -7,3 +7,6 @@ - nextTask: `NONE` The data-driven Mesh, Modifier, and Asset Catalog matrix re-runs the real WebEngine WASM Main path with one catalog hash. Positive cases change Main and pass save/reopen; stale, malformed, unknown, and collision cases remain explicit retained negatives. The matrix does not claim all inventory entries are complete or reproduce unavailable historical bytes. P10-003 is the terminal pointer until a separately authorized continuation is created. +- authorized continuation: `WBV2-P11-000` + +Module expansion may continue under a new manifest root. This does not change the P10 evidence or the authorized-rebaseline-only release scope. diff --git a/docs/status/WBV2-P11-000.md b/docs/status/WBV2-P11-000.md new file mode 100644 index 000000000..bb1ed582e --- /dev/null +++ b/docs/status/WBV2-P11-000.md @@ -0,0 +1,6 @@ +# WBV2-P11-000 status + +- task: `WBV2-P11-000`; parent: `WBV2-P10-003`; status: `done` +- nextTask: `WBV2-P11-001` + +Module expansion is authorized after P10 bound the compiled Blender native/WASM engine. P11 remains evidence-bound, Chromium-only, and explicit about the inventory remainder and authorized provenance baseline. diff --git a/docs/status/WBV2-P11-001.md b/docs/status/WBV2-P11-001.md new file mode 100644 index 000000000..6e4c256e7 --- /dev/null +++ b/docs/status/WBV2-P11-001.md @@ -0,0 +1,9 @@ +# WBV2-P11-001 status + +- task: `WBV2-P11-001`; parent: `WBV2-P11-000`; status: `done` +- topology operations: `MERGE, DISSOLVE, EXTRUDE, INSET, BEVEL, LOOP_CUT` +- real WASM Main mutations: `6/6`; revision delta: `+1 each`; save/reopen: `6/6 EXACT` +- negative cases: invalid selection, incompatible configuration, stale revision; Main unchanged +- nextTask: `WBV2-P11-002` + +The six bounded Mesh topology operations execute through the compiled WebEngine WASM Main and preserve topology summaries through save/reopen. Invalid selection, incompatible operation configuration, and stale revision fail closed. This is an engine-bound capability slice, not a claim that the complete Blender operator inventory is finished or that historical bytes were reproduced. diff --git a/docs/status/WBV2-P11-002.md b/docs/status/WBV2-P11-002.md new file mode 100644 index 000000000..c60beee90 --- /dev/null +++ b/docs/status/WBV2-P11-002.md @@ -0,0 +1,9 @@ +# WBV2-P11-002 status + +- task: `WBV2-P11-002`; parent: `WBV2-P11-001`; status: `done` +- dependency preparation: all active modifiers disabled; revision: `1 -> 4` +- DECIMATE apply: revision `4 -> 5`; vertex/triangle counts reduced +- save/reopen: `EXACT`; stale profile and malformed ratio rejected +- nextTask: `WBV2-P11-003` + +The bounded Modifier parameter/apply operation executes through the compiled WebEngine WASM Main. The dependency block is handled explicitly before apply; failed profile inputs leave the applied Main unchanged. This remains an engine-bound capability slice and does not claim complete modifier inventory parity or historical byte reproduction. diff --git a/docs/status/WBV2-P11-003.md b/docs/status/WBV2-P11-003.md new file mode 100644 index 000000000..48b165db3 --- /dev/null +++ b/docs/status/WBV2-P11-003.md @@ -0,0 +1,9 @@ +# WBV2-P11-003 status + +- task: `WBV2-P11-003`; parent: `WBV2-P11-002`; status: `done` +- linked missing-source: `EXTERNAL_REQUIRED/readOnly`; linked object withheld +- local append: `LOCAL_MAIN`; revision delta `+1`; save/reopen: `EXACT` +- stale append: `REVISION_CONFLICT`; Main unchanged +- nextTask: `WBV2-P11-004` + +The Asset link/override/reload family reuses the existing hash-bound source ownership evidence and verifies the real WebEngine WASM boundary. Missing external libraries remain explicit and do not create a fake local object; appended dependencies are local-owned and survive save/reopen. This does not claim full Asset Catalog or historical parity. diff --git a/docs/status/WBV2-P11-004.md b/docs/status/WBV2-P11-004.md new file mode 100644 index 000000000..8f221fe55 --- /dev/null +++ b/docs/status/WBV2-P11-004.md @@ -0,0 +1,12 @@ +# WBV2-P11-004 status + +- task: `WBV2-P11-004`; parent: `WBV2-P11-003`; status: `done` +- engine-bound claims: `3` +- Mesh topology: `6 operations / 6 exact save-reopen` +- Modifier parameter/apply: `DECIMATE exact` +- Asset link/override/reload: `ownership and missing-source exact` +- inventory: `6900` entries remain explicit; claimed complete: `0` +- provenance: epoch `2`, `AUTHORIZED_REBASELINE_ONLY`; fullHistoricalReproduction: `false` +- nextTask: `NONE` + +The gate emits only engine-bound Chromium claims backed by the compiled Blender native/WASM path. P7/P8/P9 history remains immutable evidence, the authorized provenance baseline is not historical restoration, and the remaining inventory is not silently marked complete. P11-004 is the terminal pointer until a separately authorized continuation is created. diff --git a/docs/tasks/WBV2-P11-000.md b/docs/tasks/WBV2-P11-000.md new file mode 100644 index 000000000..033ade528 --- /dev/null +++ b/docs/tasks/WBV2-P11-000.md @@ -0,0 +1,24 @@ +# WBV2-P11-000: module expansion continuation root + +- task: WBV2-P11-000 +- parent: WBV2-P10-003 +- status: done +- gap: workflow:authorize_module_expansion_continuation +- ownerFamily: PROGRAM +- targetImplementationClass: LOCAL_BOUNDED + +## 目标 + +Authorize module expansion after P10 proved the compiled native Blender/WASM engine path. P11 only advances engine-bound Mesh, Modifier, and Asset behavior; it does not claim complete Blender parity or historical byte reproduction. + +## 验收 + +- `node tools/web/generate-wbv2-module-expansion-root.mjs` +- `node tools/web/check-execution-control-plane.mjs` +- `node tools/web/check-v2-task-index.mjs` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P11-000/` +- Manifest: `tests/golden/WBV2-P11-000/manifest.json` +- Rollback: restore P10-003 as queue parent without rewriting P7-P10 evidence. diff --git a/docs/tasks/WBV2-P11-001.md b/docs/tasks/WBV2-P11-001.md new file mode 100644 index 000000000..ccb58baea --- /dev/null +++ b/docs/tasks/WBV2-P11-001.md @@ -0,0 +1,35 @@ +# WBV2-P11-001: Mesh topology operation family + +- task: WBV2-P11-001 +- parent: WBV2-P11-000 +- status: in_progress +- gap: workflow:mesh_topology_operation_family +- ownerFamily: MESH +- targetImplementationClass: LOCAL_EXACT + +## 目标 + +Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real compiled WebEngine WASM Main and preserve each result through save/reopen. + +## 输入与范围 + +- Mesh fixture: `tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend` +- Desktop oracle: `tests/golden/WBV2-P2-003/mesh-edit-desktop-report.json` +- WASM source report: `tests/golden/WBV2-P2-003/mesh-edit-report.json` +- Client: `web/app/src/engine-client/WebEngineClient.ts` +- Test: `web/tests/e2e/wbv2-mesh-topology-production.spec.ts` + +## 验收 + +- `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-topology-production.spec.ts` +- `node tools/web/generate-wbv2-mesh-topology-receipt.mjs --write` +- `node tools/web/check-task-context.mjs --task WBV2-P11-001 --write` + +Malformed or unsupported operation, invalid selection, stale revision, non-Chromium execution, non-exact save/reopen, or missing Main mutation must keep in_progress and must not advance nextTask. + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P11-001/` +- Status: `docs/status/WBV2-P11-001.md` +- Manifest: `tests/golden/WBV2-P11-001/manifest.json` +- Rollback: restore P11-000 as queue parent without modifying P10 evidence. diff --git a/docs/tasks/WBV2-P11-002.md b/docs/tasks/WBV2-P11-002.md new file mode 100644 index 000000000..07d7af708 --- /dev/null +++ b/docs/tasks/WBV2-P11-002.md @@ -0,0 +1,32 @@ +# WBV2-P11-002: Modifier parameter and apply family + +- task: WBV2-P11-002 +- parent: WBV2-P11-001 +- status: in_progress +- gap: workflow:modifier_parameter_apply_family +- ownerFamily: MODIFIER +- targetImplementationClass: LOCAL_EXACT + +## 目标 + +Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions. + +## 输入与范围 + +- Modifier fixture: `tests/files/web/generated/WBV2-P4-001-MODIFIER.DECLARED_SLICES.blend` +- Existing native receipt: `tests/golden/WBV2-P10-002/native-engine-receipt-report.json` +- Modifier protocol: `blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp` + +## 验收 + +- `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-parameter-production.spec.ts` +- `node tools/web/generate-wbv2-modifier-parameter-receipt.mjs --write` +- `node tools/web/check-task-context.mjs --task WBV2-P11-002 --write` + +Malformed, unsupported modifier, stale revision, failed apply, non-exact save/reopen, or missing evaluated Main mutation must keep in_progress and must not advance nextTask. + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P11-002/` +- Manifest: `tests/golden/WBV2-P11-002/manifest.json` +- Rollback: restore P11-001 as queue parent without modifying Mesh evidence. diff --git a/docs/tasks/WBV2-P11-003.md b/docs/tasks/WBV2-P11-003.md new file mode 100644 index 000000000..49ea38d96 --- /dev/null +++ b/docs/tasks/WBV2-P11-003.md @@ -0,0 +1,33 @@ +# WBV2-P11-003: Asset link, override, and reload family + +- task: WBV2-P11-003 +- parent: WBV2-P11-002 +- status: in_progress +- gap: workflow:asset_link_override_reload_family +- ownerFamily: ASSET +- targetImplementationClass: LOCAL_EXACT + +## 目标 + +Extend the real Asset Main path from append to link, local override, reload, and missing-library boundaries. + +## 输入与范围 + +- Asset fixture: `tests/files/web/generated/WBV2-P3-005-ASSET.LIBRARY_OPERATIONS.blend` +- Source library: `tests/files/web/generated/WBV2P3005Library.blend` +- Existing append receipt: `tests/golden/WBV2-P10-002/native-engine-receipt-report.json` + +## 验收 + +- `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-asset-link-override-production.spec.ts` +- `node tools/web/generate-wbv2-asset-link-override-receipt.mjs --write` +- `node tools/web/check-task-context.mjs --task WBV2-P11-003 --write` + +Malformed binding, stale source revision, ownership violation, missing resource, non-Chromium execution, or non-exact save/reopen must keep in_progress and must not advance nextTask. + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P11-003/` +- Status: `docs/status/WBV2-P11-003.md` +- Manifest: `tests/golden/WBV2-P11-003/manifest.json` +- Rollback: restore P11-002 as queue parent without modifying Mesh or Modifier evidence. diff --git a/docs/tasks/WBV2-P11-004.md b/docs/tasks/WBV2-P11-004.md new file mode 100644 index 000000000..9f1ae5d06 --- /dev/null +++ b/docs/tasks/WBV2-P11-004.md @@ -0,0 +1,33 @@ +# WBV2-P11-004: engine module parity gate + +- task: WBV2-P11-004 +- parent: WBV2-P11-003 +- status: in_progress +- gap: workflow:recompute_engine_module_gate +- ownerFamily: RELEASE +- targetImplementationClass: LOCAL_BOUNDED + +## 目标 + +Recompute engine-bound module claims from P10 and P11 receipts without claiming whole-inventory completion. + +## 输入与范围 + +- P10 engine receipt: `tests/golden/WBV2-P10-002/native-engine-receipt-report.json` +- P10 module matrix: `tests/golden/WBV2-P10-003/module-matrix-receipt-report.json` +- P11 Mesh/Modifier/Asset receipts +- Provenance approval: `docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json` + +## 验收 + +- `node tools/web/generate-wbv2-engine-module-gate.mjs --write` +- `node tools/web/check-task-context.mjs --task WBV2-P11-004 --write` + +Missing receipt, hash drift, unsupported browser, false inventory completion, false historical reproduction, or undeclared capability claim must keep in_progress and must not advance nextTask. + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P11-004/` +- Status: `docs/status/WBV2-P11-004.md` +- Manifest: `tests/golden/WBV2-P11-004/manifest.json` +- Rollback: restore P11-003 as queue parent without modifying engine receipts. diff --git a/nextTask.md b/nextTask.md index b42db39a8..d37b635e3 100644 --- a/nextTask.md +++ b/nextTask.md @@ -240,12 +240,12 @@ Recorded: 2026-08-22 America/New_York | Field | Value | | --- | --- | -| Current task when this file was written | `WBV2-P0-002` | -| Current task state | `in_progress` | -| Parent manifest | `tests/golden/WBV2-P0-001/manifest.json` | -| Current task card | `docs/tasks/WBV2-P0-002.md` | -| Current task-context nextTask | `WBV2-P0-003` | -| Focused command | `node tools/web/check-execution-control-plane.mjs` | +| Current task when this file was written | `WBV2-P11-004` | +| Current task state | `done` | +| Parent manifest | `tests/golden/WBV2-P11-003/manifest.json` | +| Current task card | `docs/tasks/WBV2-P11-004.md` | +| Current task-context nextTask | `NONE` | +| Focused command | `node tools/web/generate-wbv2-engine-module-gate.mjs --write` | The snapshot is informational and may become stale. On every resume, the queue, parent manifest, and fresh `print-task-context` output win. Never infer a task diff --git a/tests/golden/WBV2-P10-003/manifest.json b/tests/golden/WBV2-P10-003/manifest.json index 5acfebb25..8cd181d07 100644 --- a/tests/golden/WBV2-P10-003/manifest.json +++ b/tests/golden/WBV2-P10-003/manifest.json @@ -42,11 +42,11 @@ }, "report": { "path": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json", - "sha256": "655d05c7f1c9d55d76f41c063b89ef5cd49abf0fb4f01f2cd6d7b2a5f1fa7f14" + "sha256": "6d66635d900762809f82e73464ac298944514d25ac5172d2c697181cffeb7b8d" }, "status": { "path": "docs/status/WBV2-P10-003.md", - "sha256": "ce391ea8cdc0ec25d523226a93a3ddfac718e9c70292ab80cd02c9c8f2d1fc69" + "sha256": "29ca4baeca2ab385f1de3367c65b4bb8c91ff26598d739c68936732a8293a08c" }, "parityPlan": { "path": "tests/golden/WBV2-P10-003/native-parity-task-plan.json", @@ -54,7 +54,7 @@ }, "taskContext": { "path": "tests/golden/WBV2-P10-003/task-context.json", - "sha256": "ed59f7698d14e39b197e3798ed704bfb8f1783002c1ff97901d604bda4d97bf2" + "sha256": "d1a738ab3faff04087d47c3629ef6d053ba6bfbf550141785925442207a4ef2d" } }, "assertions": { @@ -69,5 +69,10 @@ "saveReopen": "EXACT", "historicalReproduction": false }, - "nextTask": null + "nextTask": "WBV2-P11-000", + "continuation": { + "authorized": true, + "root": "WBV2-P11-000", + "scope": "MODULE_EXPANSION" + } } diff --git a/tests/golden/WBV2-P10-003/module-matrix-receipt-report.json b/tests/golden/WBV2-P10-003/module-matrix-receipt-report.json index 8e7b22903..eb6a63f23 100644 --- a/tests/golden/WBV2-P10-003/module-matrix-receipt-report.json +++ b/tests/golden/WBV2-P10-003/module-matrix-receipt-report.json @@ -61,5 +61,9 @@ "retainedNegativeExplicit": true, "historicalReproduction": false }, - "nextTask": null + "nextTask": "WBV2-P11-000", + "policy": { + "terminalQueuePointer": false, + "authorizedContinuation": "WBV2-P11-000" + } } diff --git a/tests/golden/WBV2-P10-003/task-context.json b/tests/golden/WBV2-P10-003/task-context.json index 1840d6536..7b6d071bc 100644 --- a/tests/golden/WBV2-P10-003/task-context.json +++ b/tests/golden/WBV2-P10-003/task-context.json @@ -73,7 +73,7 @@ "shards use one catalog hash", "unmapped and retained-negative cases stay explicit" ], - "nextTask": null, + "nextTask": "WBV2-P11-000", "sourceDocuments": { "queue": "docs/EXECUTION_QUEUE.md", "taskCard": "docs/tasks/WBV2-P10-003.md", @@ -170,7 +170,7 @@ "totalTokens": 2099, "reservedEnvelopeTokens": 1024, "estimatedContextTokens": 3123, - "serializedContextTokens": 688, + "serializedContextTokens": 690, "withinBudget": true } } diff --git a/tests/golden/WBV2-P11-000/manifest.json b/tests/golden/WBV2-P11-000/manifest.json new file mode 100644 index 000000000..581949737 --- /dev/null +++ b/tests/golden/WBV2-P11-000/manifest.json @@ -0,0 +1,55 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-000", + "parentTask": "WBV2-P10-003", + "operation": "AUTHORIZE_MODULE_EXPANSION_CONTINUATION", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P10-003/manifest.json", + "sha256": "5c0ce2665b5509e8c9551164c463c60d8e89b5bf13a596980321bdb343dd2c8d" + }, + "parentReport": { + "path": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json", + "sha256": "6d66635d900762809f82e73464ac298944514d25ac5172d2c697181cffeb7b8d" + }, + "approval": { + "path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", + "sha256": "cffc869734af94ffe6b8b8004d7ab8cc2c9edcb85ec2a877548e0b0f923f5ea3" + }, + "plan": { + "path": "tests/golden/WBV2-P11-000/module-expansion-task-plan.json", + "sha256": "e1280465871db20dd8952f6f5949971ea5bee57a6191000247ac51b6f28cc39a" + }, + "report": { + "path": "tests/golden/WBV2-P11-000/module-expansion-root-report.json", + "sha256": "05221d113d79853596f984b34f6fd983daa9302d800c209ac417f2e1341b6cb6" + }, + "rootCard": { + "path": "docs/tasks/WBV2-P11-000.md", + "sha256": "bdfe2420439b3a5d36d044777194cf3e2763384f460109c679a6fa7d16b0fba7" + }, + "rootStatus": { + "path": "docs/status/WBV2-P11-000.md", + "sha256": "97d56508dd5c66d5915f74de76e3782303a9cd137cfe26490c751d8e6739fe62" + }, + "activeCard": { + "path": "docs/tasks/WBV2-P11-001.md", + "sha256": "0982f523f8258c9e3ec861d9caa6076abb4a79b3d62ece5936cd326a20e15180" + } + }, + "assertions": { + "p10EvidencePreserved": true, + "nativeEngineAlreadyBound": true, + "moduleExpansionScope": [ + "MESH_TOPOLOGY", + "MODIFIER_PARAMETER_APPLY", + "ASSET_LINK_OVERRIDE_RELOAD" + ], + "authorizedRebaselineOnly": true, + "fullHistoricalReproduction": false + }, + "nextTask": "WBV2-P11-001" +} diff --git a/tests/golden/WBV2-P11-000/module-expansion-root-report.json b/tests/golden/WBV2-P11-000/module-expansion-root-report.json new file mode 100644 index 000000000..d6ff96079 --- /dev/null +++ b/tests/golden/WBV2-P11-000/module-expansion-root-report.json @@ -0,0 +1,34 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-000", + "operation": "AUTHORIZE_MODULE_EXPANSION_CONTINUATION", + "status": "PASS", + "parent": { + "task": "WBV2-P10-003", + "manifest": "tests/golden/WBV2-P10-003/manifest.json", + "manifestSha256": "efe72a12f0b1f5d2d109768b37019eacb9e69f40921dd92f70f1acef06ef6593", + "previousDecision": "CORE_MODULE_OPERATOR_MATRIX_RECEIPT", + "fullHistoricalReproduction": false + }, + "continuation": { + "root": "WBV2-P11-000", + "firstTask": "WBV2-P11-001", + "plannedTasks": 5, + "scope": [ + "MESH_TOPOLOGY", + "MODIFIER_PARAMETER_APPLY", + "ASSET_LINK_OVERRIDE_RELOAD", + "ENGINE_MODULE_GATE" + ], + "browser": "chromium", + "nativeEngineAlreadyBound": true + }, + "policy": { + "historicalEvidencePreserved": true, + "authorizedRebaselineOnly": true, + "engineClaimsEvidenceBound": true, + "fullHistoricalReproduction": false, + "inventoryRemainderExplicit": true + }, + "nextTask": "WBV2-P11-001" +} diff --git a/tests/golden/WBV2-P11-000/module-expansion-task-plan.json b/tests/golden/WBV2-P11-000/module-expansion-task-plan.json new file mode 100644 index 000000000..f30840c05 --- /dev/null +++ b/tests/golden/WBV2-P11-000/module-expansion-task-plan.json @@ -0,0 +1,1716 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_MODULE_EXPANSION_EPOCH_1", + "status": "ACTIVE_MODULE_EXPANSION_QUEUE", + "authority": "queue_reactivated_after_p10_engine_matrix", + "productContract": "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "sourcePlan": "docs/BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "correctiveCheckpoint": { + "task": "C6-003", + "handoff": "tests/golden/corrective/C6-003/handoff.json", + "status": "active", + "blocker": null, + "queueMutation": true, + "legacyTask": "M16-GAP-00277", + "legacyParentNextTask": "M16-GAP-00277" + }, + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "storage": [ + "opfs", + "indexeddb" + ], + "queueMutation": "enabled_after_owner_review_and_g5" + }, + "completionClasses": [ + "LOCAL_EXACT", + "LOCAL_BOUNDED", + "SERVER_EXACT", + "EXCLUDED" + ], + "gates": [ + { + "id": "G0", + "name": "scope_and_inventory", + "requires": [ + "contract", + "inventory", + "capability_matrix" + ] + }, + { + "id": "G1", + "name": "runtime_foundation", + "requires": [ + "sceneir", + "main_transaction", + "worker_lifecycle", + "storage_journal" + ] + }, + { + "id": "G2", + "name": "feature_parity", + "requires": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence" + ] + }, + { + "id": "G3", + "name": "recovery_and_security", + "requires": [ + "cancel", + "restart", + "oom_quota", + "malformed", + "dispose" + ] + }, + { + "id": "G4", + "name": "release_candidate", + "requires": [ + "offline", + "ci", + "sbom", + "rollback", + "hashes" + ] + }, + { + "id": "G5", + "name": "queue_mutation", + "requires": [ + "owner_review", + "protected_hashes", + "handoff", + "single_ready_task" + ] + } + ], + "waves": [ + { + "id": "P0", + "name": "facts_and_contracts", + "gate": "G0", + "tasks": [ + "WBV2-P0-001", + "WBV2-P0-002", + "WBV2-P0-003" + ] + }, + { + "id": "P1", + "name": "runtime_foundation", + "gate": "G1", + "tasks": [ + "WBV2-P1-001", + "WBV2-P1-002", + "WBV2-P1-003", + "WBV2-P1-004", + "WBV2-P1-005" + ] + }, + { + "id": "P2", + "name": "core_modeler_loop", + "gate": "G2", + "tasks": [ + "WBV2-P2-001", + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P2-005" + ] + }, + { + "id": "P3", + "name": "authoring_and_io", + "gate": "G2", + "tasks": [ + "WBV2-P3-001", + "WBV2-P3-002", + "WBV2-P3-003", + "WBV2-P3-004", + "WBV2-P3-005" + ] + }, + { + "id": "P4", + "name": "advanced_local_slices", + "gate": "G2", + "tasks": [ + "WBV2-P4-001", + "WBV2-P4-002", + "WBV2-P4-003", + "WBV2-P4-004" + ] + }, + { + "id": "P5", + "name": "render_and_server", + "gate": "G3", + "tasks": [ + "WBV2-P5-001", + "WBV2-P5-002", + "WBV2-P5-003" + ] + }, + { + "id": "P6", + "name": "security_performance_release", + "gate": "G4", + "tasks": [ + "WBV2-P6-001", + "WBV2-P6-002", + "WBV2-P6-003" + ] + }, + { + "id": "P7", + "name": "full_parity_gap_program", + "gate": "G5", + "tasks": [ + "WBV2-P7-001", + "WBV2-P7-002", + "WBV2-P7-003" + ] + } + ], + "taskContract": { + "onePrimaryBehavior": true, + "requiredEvidence": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence", + "manifest", + "status" + ], + "requiredCommands": [ + "focused", + "determinism", + "hash", + "governance" + ], + "failureState": "in_progress_or_blocked", + "successorRule": "only_from_parent_manifest_nextTask" + }, + "tasks": [ + { + "id": "WBV2-P0-001", + "phase": "P0", + "title": "reconcile_scope_and_checkpoints", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-governance", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-001.md", + "behavior": "Freeze V1/full-parity boundary and reconcile legacy/corrective pointers without queue mutation.", + "outputs": [ + "scope decision", + "checkpoint report", + "protected hash set" + ], + "acceptance": [ + "corrective owner-review status is explicit", + "legacy parent pointer is unchanged", + "plan has one activation gate" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-002", + "phase": "P0", + "title": "generate_blender52_inventory_and_parity_map", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-inventory", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-002.md", + "behavior": "Generate stable Blender 5.2 data-block/operator/editor/node/format inventory and map every entry to a completion class.", + "outputs": [ + "inventory", + "parity map", + "source hash" + ], + "acceptance": [ + "unknown entries are classified", + "inventory is deterministic", + "no entry claims feature parity without evidence" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-003", + "phase": "P0", + "title": "freeze_capability_error_budget_contract", + "kind": "enabling", + "owner": "PROTOCOL", + "dependsOn": [ + "WBV2-P0-001", + "WBV2-P0-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-contract", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-003.md", + "behavior": "Freeze capability levels, stable error codes, revision, budget, cancellation and loss-report schemas.", + "outputs": [ + "versioned protocol", + "capability matrix", + "negative matrix" + ], + "acceptance": [ + "unsupported input fails closed", + "schema hashes are stable", + "migration policy preserves unknown data" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-001", + "phase": "P1", + "title": "stabilize_runtime_variants_and_source_receipts", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P0-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-runtime", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-001.md", + "behavior": "Bind single-thread/pthread WebEngine variants to pinned Blender source/build/runtime receipts.", + "outputs": [ + "runtime manifest", + "variant selector", + "fallback report" + ], + "acceptance": [ + "variant fallback is deterministic", + "source/build hash is verified", + "one engine session has one generation" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-002", + "phase": "P1", + "title": "unify_sceneir_stable_ids_and_binary_deltas", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-001" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-sceneir", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-002.md", + "behavior": "Make SceneIR/WBG1 stable IDs, topology/attribute domains and binary/range deltas canonical across desktop and WASM.", + "outputs": [ + "SceneIR schema", + "binary fixture", + "delta comparator" + ], + "acceptance": [ + "IDs survive save/reopen", + "malformed chunk is rejected", + "desktop and WASM canonical hashes match" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-003", + "phase": "P1", + "title": "unify_main_transaction_history_and_save", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-002" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-history", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-003.md", + "behavior": "Use one Main transaction/revision/history contract for commit, undo/redo, atomic save and reopen.", + "outputs": [ + "transaction contract", + "history receipt", + "save/reopen runner" + ], + "acceptance": [ + "failed/no-op commands add no history", + "stale revision cannot commit", + "reopen state is byte/hash stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-004", + "phase": "P1", + "title": "harden_worker_cancel_restart_and_dispose", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P1-001", + "WBV2-P1-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-lifecycle", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-004.md", + "behavior": "Make cancellation, late-result rejection, Worker restart and resource disposal common to all domains.", + "outputs": [ + "lifecycle runner", + "fault report", + "dispose counters" + ], + "acceptance": [ + "cancel never publishes result", + "generation mismatch is rejected", + "CPU/WASM/GPU owners return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-005", + "phase": "P1", + "title": "harden_opfs_indexeddb_journal_recovery", + "kind": "enabling", + "owner": "STORAGE", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P1-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-storage", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-005.md", + "behavior": "Unify OPFS staging/content addressing and IndexedDB metadata/journal recovery.", + "outputs": [ + "storage schema", + "crash fixtures", + "recovery checker" + ], + "acceptance": [ + "interrupted commit leaves old project usable", + "hash mismatch quarantines payload", + "small project recovers after restart" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-001", + "phase": "P2", + "title": "open_blend_scene_context_and_outliner", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P1-005" + ], + "parityId": "EDITOR.OPEN_SCENE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-editor", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-001.md", + "behavior": "Open a minimal .blend and expose scene/object/collection context from authoritative Main.", + "outputs": [ + "desktop fixture", + "outliner report", + "Chromium path" + ], + "acceptance": [ + "stable IDs and selection revision match", + "missing data is structured", + "reopen preserves context" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-002", + "phase": "P2", + "title": "object_collection_parent_transform_workflow", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P2-001" + ], + "parityId": "OBJECT.TRANSFORM_HIERARCHY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-scene", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-002.md", + "behavior": "Edit object transform, collection membership and parent hierarchy through Main transactions.", + "outputs": [ + "desktop/WASM golden", + "negative cases", + "save/reopen receipt" + ], + "acceptance": [ + "world matrix parity", + "cycle/locked/library edits reject", + "undo/redo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-003", + "phase": "P2", + "title": "mesh_edit_core_operations", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P2-002" + ], + "parityId": "MESH.EDIT_CORE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-mesh", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-003.md", + "behavior": "Expose bounded vertex/edge/face selection plus merge/dissolve/extrude/inset/bevel/loop-cut.", + "outputs": [ + "Blender fixture set", + "topology comparator", + "Chromium edit path" + ], + "acceptance": [ + "topology/attributes match", + "invalid selection and budget fail closed", + "single transaction and reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-004", + "phase": "P2", + "title": "dual_viewport_sceneir_render_path", + "kind": "feature", + "owner": "VIEWPORT", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P2-003" + ], + "parityId": "VIEWPORT.MAIN_OFFSCREEN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-viewport", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-004.md", + "behavior": "Render the same validated SceneIR through main-thread WebGL2 and OffscreenCanvas Worker paths.", + "outputs": [ + "pixel report", + "viewport diagnostics", + "device recovery" + ], + "acceptance": [ + "both paths have nonblank pixels", + "selection/camera revision is shared", + "device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-005", + "phase": "P2", + "title": "close_p0_user_loop", + "kind": "feature", + "owner": "INTEGRATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P1-005", + "WBV2-P2-004" + ], + "parityId": "WORKFLOW.P0_USER_LOOP", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-integration", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-005.md", + "behavior": "Prove open -> edit -> undo -> redo -> save -> restart -> reopen -> GLB in one production flow.", + "outputs": [ + "P0 workflow report", + "release binding", + "rollback receipt" + ], + "acceptance": [ + "Main revision and exported asset are bound", + "fault/cancel leaves old state", + "Chromium production path passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-001", + "phase": "P3", + "title": "material_uv_principled_asset_workflow", + "kind": "feature", + "owner": "MATERIAL", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005" + ], + "parityId": "MATERIAL.PBR_UV", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-001.md", + "behavior": "Edit material slots, UVs and declared Principled/Image/Normal graph nodes with content-addressed textures.", + "outputs": [ + "material golden", + "texture receipt", + "loss report" + ], + "acceptance": [ + "desktop/WASM node fields match", + "unsupported node retained/blocked", + "packed asset survives reopen" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-002", + "phase": "P3", + "title": "keyframe_timeline_action_workflow", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-005", + "WBV2-P3-001" + ], + "parityId": "ANIMATION.TRS_ACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-002.md", + "behavior": "Create/edit TRS keyframes, timeline and declared Action interpolation through Main.", + "outputs": [ + "frame golden", + "animation comparator", + "reopen report" + ], + "acceptance": [ + "sampled values and handles match", + "stale frame result rejected", + "undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-003", + "phase": "P3", + "title": "armature_pose_constraint_skin_workflow", + "kind": "feature", + "owner": "RIG", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P3-002" + ], + "parityId": "RIG.POSE_SKIN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-rig", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-003.md", + "behavior": "Read and edit declared armature pose/constraint/weight/shape-key slices with bounded evaluation.", + "outputs": [ + "pose golden", + "skin report", + "unsupported matrix" + ], + "acceptance": [ + "pose matrices and weights match", + "unsupported constraint is explicit", + "save/reopen and small recovery pass" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-004", + "phase": "P3", + "title": "glb_roundtrip_and_loss_report", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P2-005", + "WBV2-P3-001", + "WBV2-P3-003" + ], + "parityId": "IO.GLB_ROUNDTRIP", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-io", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-004.md", + "behavior": "Import/export declared GLB mesh/PBR/texture/morph/skin/animation and report non-mapped semantics.", + "outputs": [ + "GLB fixtures", + "desktop reimport report", + "loss report" + ], + "acceptance": [ + "roundtrip canonical graph matches", + "sparse/external URI/budget negatives reject", + "no silent loss" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-005", + "phase": "P3", + "title": "library_asset_append_link_override", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P2-001", + "WBV2-P3-004" + ], + "parityId": "ASSET.LIBRARY_OPERATIONS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-assets", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-005.md", + "behavior": "Support declared append/link/override ownership, reload and missing-library semantics.", + "outputs": [ + "library fixtures", + "ownership report", + "negative matrix" + ], + "acceptance": [ + "source/hash/owner identity preserved", + "linked mutation blocked", + "stale generation and missing source fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-001", + "phase": "P4", + "title": "modifier_graph_and_apply_slices", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005", + "WBV2-P3-005" + ], + "parityId": "MODIFIER.DECLARED_SLICES", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-001.md", + "behavior": "Enable one declared modifier parameter/apply workflow at a time with dependency-aware blocking.", + "outputs": [ + "modifier goldens", + "dependency report", + "negative cases" + ], + "acceptance": [ + "desktop/evaluated Main match", + "unknown modifier retained and blocked", + "apply/undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-002", + "phase": "P4", + "title": "geometry_nodes_and_shader_allowlist", + "kind": "feature", + "owner": "NODES", + "dependsOn": [ + "WBV2-P3-001", + "WBV2-P4-001" + ], + "parityId": "NODES.ALLOWLIST", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-002.md", + "behavior": "Read/write/evaluate only declared Geometry Nodes and shader graph allowlists with resource budgets.", + "outputs": [ + "node fixtures", + "compile/cache receipts", + "unsupported graph reports" + ], + "acceptance": [ + "node/socket/link/default parity", + "budget and unknown-node block before commit", + "compile failure rolls back" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-003", + "phase": "P4", + "title": "sculpt_nonmesh_and_paint_bounded_slices", + "kind": "feature", + "owner": "SCULPT", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P4-002" + ], + "parityId": "SCULPT.NONMESH.PAINT_BOUNDED", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-003.md", + "behavior": "Expose declared sculpt attributes/strokes, Curve/Surface/Font/PointCloud and paint slices with explicit PBVH limits.", + "outputs": [ + "non-mesh fixtures", + "stroke report", + "capability blocks" + ], + "acceptance": [ + "Main commit is atomic", + "unsupported brush/solver returns stable code", + "GPU/OOM/restart recovery passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-004", + "phase": "P4", + "title": "simulation_cache_identity_and_lifecycle", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P4-002", + "WBV2-P4-003" + ], + "parityId": "SIMULATION.CACHE_LIFECYCLE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G3", + "card": "docs/tasks/WBV2-P4-004.md", + "behavior": "Bind declared simulation cache to source/settings/revision hashes with cancellation, LRU and restart recovery.", + "outputs": [ + "cache fixtures", + "identity report", + "quarantine evidence" + ], + "acceptance": [ + "stale/corrupt cache never publishes", + "small cache recovers after restart", + "budget release is observable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-001", + "phase": "P5", + "title": "render_capability_routing", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P2-004", + "WBV2-P4-002", + "WBV2-P4-004" + ], + "parityId": "RENDER.ROUTING", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-001.md", + "behavior": "Route bounded Eevee/WebGL capabilities locally and unsupported render classes to SERVER_EXACT or EXCLUDED.", + "outputs": [ + "render receipts", + "pixel golden", + "routing report" + ], + "acceptance": [ + "source/settings/build identity bound", + "unsupported route cannot pretend local success", + "cancel/device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-002", + "phase": "P5", + "title": "compositor_sequencer_media_recovery", + "kind": "feature", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P3-002", + "WBV2-P5-001" + ], + "parityId": "MEDIA.BOUNDED_WORKFLOW", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-002.md", + "behavior": "Provide declared compositor/sequencer/codec/proxy/audio slices with revision and recovery gates.", + "outputs": [ + "media receipts", + "recovery report", + "audio/session diagnostics" + ], + "acceptance": [ + "seek/decode revision ordering", + "cancel/timeout does not publish", + "quota/OOM/restart leaves project valid" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-003", + "phase": "P5", + "title": "server_job_result_binding", + "kind": "feature", + "owner": "SERVER", + "dependsOn": [ + "WBV2-P0-003", + "WBV2-P5-001", + "WBV2-P5-002" + ], + "parityId": "SERVER.JOB_BINDING", + "implementationClass": "SERVER_EXACT", + "parallelGroup": "p5-server", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-003.md", + "behavior": "Bind server render/encode/physics jobs to immutable input/settings/build/output hashes and explicit lifecycle states.", + "outputs": [ + "server protocol", + "idempotency receipt", + "negative matrix" + ], + "acceptance": [ + "duplicate request is idempotent", + "stale result cannot bind", + "timeout/cancel/OOM produces no READY output" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-001", + "phase": "P6", + "title": "scripting_default_deny_and_audit", + "kind": "feature", + "owner": "SECURITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P5-003" + ], + "parityId": "SECURITY.SCRIPTING", + "implementationClass": "EXCLUDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-001.md", + "behavior": "Read text/metadata and expose audited, budgeted, default-deny script policy without arbitrary execution.", + "outputs": [ + "policy manifest", + "malicious fixtures", + "audit report" + ], + "acceptance": [ + "autorun/network/add-on defaults deny", + "sandbox cancellation/dispose works", + "no secret or filesystem escape" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-002", + "phase": "P6", + "title": "performance_fault_and_recovery_matrix", + "kind": "enabling", + "owner": "RELIABILITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P1-005", + "WBV2-P2-004", + "WBV2-P6-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-002.md", + "behavior": "Run deterministic geometry/texture/media/cache budgets and inject OOM/quota/device/network faults.", + "outputs": [ + "budget matrix", + "fault reports", + "resource release ledger" + ], + "acceptance": [ + "100k/1M/10M thresholds recorded", + "fault leaves old revision usable", + "all owned resources return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-003", + "phase": "P6", + "title": "offline_ci_sbom_and_rollback_release", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P6-001", + "WBV2-P6-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-release", + "gate": "G4", + "card": "docs/tasks/WBV2-P6-003.md", + "behavior": "Produce reproducible offline/source/binary release packages with CI lanes, SBOM and rollback evidence.", + "outputs": [ + "RC manifest", + "offline archive", + "CI reports" + ], + "acceptance": [ + "quick/Chromium/release lanes pass", + "artifact hashes reproduce", + "upgrade/rollback and known limitations are tested" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-001", + "phase": "P7", + "title": "cluster_full_blender_gap_inventory", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-002", + "WBV2-P6-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-001.md", + "behavior": "Cluster remaining Blender 5.2 data-block/operator/editor/node/format gaps by family and evidence class.", + "outputs": [ + "cluster catalog", + "coverage report", + "risk ranking" + ], + "acceptance": [ + "each gap has stable ID and owner", + "negative-only/unsupported is not positive parity", + "clusters are deterministic" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-002", + "phase": "P7", + "title": "generate_atomic_family_gap_queue", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-002.md", + "behavior": "Generate one task per parityId x observable behavior x implementation class with parent/hash context.", + "outputs": [ + "task index", + "task catalog", + "task cards" + ], + "acceptance": [ + "one active ready task", + "no guessed successor", + "each card fits context budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-003", + "phase": "P7", + "title": "full_parity_candidate_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P7-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P7-003.md", + "behavior": "Recompute parity closure, evidence health, recovery health and release decision from machine manifests.", + "outputs": [ + "parity release report", + "known limitations", + "final decision" + ], + "acceptance": [ + "all claims bind to evidence", + "blocked/excluded/server classes remain explicit", + "queue and protected hashes pass" + ], + "status": "blocked", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-000", + "phase": "P8", + "title": "authorize_recovery_capability_root", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-000.md", + "behavior": "Authorize a recovery epoch without rewriting the blocked P7 manifest.", + "outputs": [ + "recovery plan", + "root manifest", + "queue authorization" + ], + "acceptance": [ + "P7 evidence remains hash exact", + "recovery scope is explicit", + "one recovery task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P8-001", + "phase": "P8", + "title": "rebaseline_mutable_inventories", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-001.md", + "behavior": "Rebaseline mutable WBV2 plan and dependency inventory inputs while preserving historical manifests.", + "outputs": [ + "semantic drift report", + "current inventory baseline", + "manifest" + ], + "acceptance": [ + "only expected mutable hashes drift", + "dependency closure is unchanged", + "historical manifests remain unmodified" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-002", + "phase": "P8", + "title": "close_atomic_chromium_receipts", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P8-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-receipts", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-002.md", + "behavior": "Produce and bind all 45 atomic Chromium family receipts.", + "outputs": [ + "Chromium report", + "45 receipt index", + "receipt manifests" + ], + "acceptance": [ + "45 receipts are manifest-bound", + "desktop/WASM/save-reopen behaviors are explicit", + "Chromium is the only browser" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-003", + "phase": "P8", + "title": "authorize_m12_provenance_epoch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-provenance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-003.md", + "behavior": "Bind restored M12 sources and explicitly rebaseline unavailable originals in a new provenance epoch.", + "outputs": [ + "provenance epoch", + "replacement bindings", + "manifest" + ], + "acceptance": [ + "22 restored originals stay exact", + "62 unavailable entries are not called restored", + "all replacements are hash-bound" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-004", + "phase": "P8", + "title": "recompute_recovery_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P8-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-004.md", + "behavior": "Recompute the release decision from the recovery epoch and atomic receipts.", + "outputs": [ + "release gate", + "known limitations", + "final manifest" + ], + "acceptance": [ + "all receipts bind to manifests", + "provenance epoch is explicit", + "all governance gates pass" + ], + "status": "in_progress", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-000", + "phase": "P9", + "title": "authorize_feature_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-000.md", + "behavior": "Authorize feature parity continuation after provenance epoch 2 without claiming historical byte reproduction.", + "outputs": [ + "continuation receipt", + "feature parity plan", + "scope limits" + ], + "acceptance": [ + "P8 provenance evidence remains exact", + "authorized baseline is explicit", + "one feature task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P9-001", + "phase": "P9", + "title": "mesh_production_chromium_receipt", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P9-000" + ], + "parityId": "CAP-MESH-POSITIVE-EDIT", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-mesh", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-001.md", + "behavior": "Bind the existing Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt.", + "outputs": [ + "Chromium mesh receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real meshTranslateVertex command passes", + "desktop/WASM delta matches", + "save/reopen is exact", + "malformed/stale/unknown inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-002", + "phase": "P9", + "title": "modifier_production_chromium_receipt", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P9-001" + ], + "parityId": "CAP-MODIFIER-STATE-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-modifier", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-002.md", + "behavior": "Bind the existing Modifier Main transaction to a production Chromium receipt.", + "outputs": [ + "Chromium modifier receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real modifierSetEnabled command passes", + "desktop/WASM delta matches", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-003", + "phase": "P9", + "title": "asset_catalog_production_chromium_receipt", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P9-002" + ], + "parityId": "CAP-ASSET-CATALOG-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-asset", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-003.md", + "behavior": "Bind the existing Asset Catalog Main transaction and resource resolver to a production Chromium receipt.", + "outputs": [ + "Chromium asset receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real assetCatalogAppend command passes", + "resource hash is bound", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-004", + "phase": "P9", + "title": "recompute_feature_parity_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P9-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-release", + "gate": "G7", + "card": "docs/tasks/WBV2-P9-004.md", + "behavior": "Recompute declared feature parity claims from production Chromium receipts and authorized provenance.", + "outputs": [ + "feature parity gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only evidenced feature claims are emitted", + "authorized baseline remains explicit", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-000", + "phase": "P10", + "title": "authorize_native_engine_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P9-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-000.md", + "behavior": "Authorize native Blender/WASM engine parity continuation after bounded Chromium capability evidence.", + "outputs": [ + "continuation receipt", + "native parity plan", + "scope limits" + ], + "acceptance": [ + "P9 evidence remains hash-bound", + "native build/runtime is explicit", + "one native parity task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P10-001", + "phase": "P10", + "title": "reconcile_wbv2_inventory_source_drift", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-inventory", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-001.md", + "behavior": "Record the authorized mutable WBV2 plan drift and prove dependency closure stability without rewriting historical P0 evidence.", + "outputs": [ + "current source hash baseline", + "drift report", + "checker compatibility" + ], + "acceptance": [ + "historical P0 hashes remain unchanged", + "only authorized plan drift is recorded", + "dependency roots/lockfile/closure remain stable", + "inventory checker passes using current baseline" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-002", + "phase": "P10", + "title": "bind_native_and_wasm_engine_receipts", + "kind": "feature", + "owner": "ENGINE", + "dependsOn": [ + "WBV2-P10-001" + ], + "parityId": "ENGINE.NATIVE_WASM_BRIDGE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p10-engine", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-002.md", + "behavior": "Bind Mesh, Modifier, and Asset Catalog receipts to the compiled Blender native binary and web_engine.wasm runtime.", + "outputs": [ + "native receipt", + "WASM receipt", + "Chromium engine report" + ], + "acceptance": [ + "native Blender binary is source-bound", + "WASM binary and JS are hash-bound", + "same mutation reaches real engine/Main", + "save/reopen and failures remain exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-003", + "phase": "P10", + "title": "expand_core_module_operator_matrix", + "kind": "feature", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-002" + ], + "parityId": "CORE.MODULE_MATRIX", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-matrix", + "gate": "G7", + "card": "docs/tasks/WBV2-P10-003.md", + "behavior": "Expand the three proven capability modules with data-driven operator coverage and aggregate regression receipts.", + "outputs": [ + "module matrix", + "shard reports", + "aggregate manifest" + ], + "acceptance": [ + "positive cases are L2+", + "negative cases do not mutate Main", + "shards use one catalog hash", + "unmapped and retained-negative cases stay explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-000", + "phase": "P11", + "title": "authorize_module_expansion_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P10-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-governance", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-000.md", + "behavior": "Authorize deeper module production after real native/WASM engine binding and the first aggregate matrix.", + "outputs": [ + "continuation root", + "module expansion plan", + "scope limits" + ], + "acceptance": [ + "P10 evidence remains hash-bound", + "one expansion task is active", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P11-001", + "phase": "P11", + "title": "mesh_topology_operation_family", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P11-000" + ], + "parityId": "MESH.EDIT_TOPOLOGY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-mesh", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-001.md", + "behavior": "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real Blender WASM Main and preserve each result through save/reopen.", + "outputs": [ + "topology receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "six mesh operations mutate Main", + "revision increments exactly once", + "save/reopen preserves topology counts", + "invalid selection and incompatible configuration fail closed" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-002", + "phase": "P11", + "title": "modifier_parameter_apply_family", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P11-001" + ], + "parityId": "MODIFIER.PARAMETER_APPLY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-modifier", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-002.md", + "behavior": "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", + "outputs": [ + "modifier parameter receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "parameter mutation is native/WASM bound", + "apply result is evaluated", + "save/reopen is exact", + "dependency and stale inputs fail closed" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-003", + "phase": "P11", + "title": "asset_link_override_reload_family", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P11-002" + ], + "parityId": "ASSET.LINK_OVERRIDE_RELOAD_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-asset", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-003.md", + "behavior": "Extend the real Asset Main path from append to link, override, reload, and missing-library boundaries.", + "outputs": [ + "asset ownership receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "source ownership is preserved", + "override is local and hash-bound", + "reload revision is checked", + "missing source remains explicit" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-004", + "phase": "P11", + "title": "recompute_engine_module_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P11-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-release", + "gate": "G8", + "card": "docs/tasks/WBV2-P11-004.md", + "behavior": "Recompute engine-bound module parity from P10 and P11 receipts without claiming whole-inventory completion.", + "outputs": [ + "engine module gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only engine-bound claims are emitted", + "inventory remainder is explicit", + "provenance epoch 2 remains authorized rebaseline only", + "full historical reproduction remains false" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ], + "parentPlan": { + "path": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "sha256": "0f4750e45f2d1ca7d68faa35743e5b758ea8091f18d1d0e312ab548228d6f782" + }, + "recoveryRoot": "WBV2-P11-000", + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P10-003/native-parity-task-plan.json", + "sha256": "acfe344c377cbef5b0eefaba22fab88de7d374e9a157ad53930ac6599cd6b1a9" + } +} diff --git a/tests/golden/WBV2-P11-001/manifest.json b/tests/golden/WBV2-P11-001/manifest.json new file mode 100644 index 000000000..284cebe5d --- /dev/null +++ b/tests/golden/WBV2-P11-001/manifest.json @@ -0,0 +1,74 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-001", + "parentTask": "WBV2-P11-000", + "operation": "MESH_TOPOLOGY_OPERATION_FAMILY_RECEIPT", + "status": "done", + "enablingTask": false, + "parityStateChange": true, + "runtime": "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P11-000/manifest.json", + "sha256": "2eb9bb41f116f13b019bda76545dfce6739cbc5940a22f40cc26e8571ddad6ff" + }, + "sourceManifest": { + "path": "tests/golden/WBV2-P2-003/manifest.json", + "sha256": "79ebc20719fef2b60a3457bca25dac98e755a2f2c1bd3c35361527509a91a987" + }, + "sourceReport": { + "path": "tests/golden/WBV2-P2-003/mesh-edit-report.json", + "sha256": "f8bd2ced2e1345248d4b536ef045bb9446a55ca5ae87d834f38904b86521b11d" + }, + "production": { + "path": "tests/golden/WBV2-P11-001/mesh-topology-production.json", + "sha256": "206e30ba61dc169364f6279464f98afd4885390a155e5de2f4e3de3990d5896d" + }, + "productionSecond": { + "path": "tests/golden/WBV2-P11-001/mesh-topology-production.second.json", + "sha256": "206e30ba61dc169364f6279464f98afd4885390a155e5de2f4e3de3990d5896d" + }, + "e2e": { + "path": "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", + "sha256": "ea773184a2a6c7c1f17cd32a390032701dffdb6debaedf9560614d421279ea47" + }, + "protocol": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "sha256": "3c31a049714860cc89c5b28ebad887a1978df11f8c528c3dfd7836635ed62fb3" + }, + "client": { + "path": "web/app/src/engine-client/WebEngineClient.ts", + "sha256": "f6d9a8e0a16403bc6fb765195b8f1a619a28de7a75c59a412f1654d46e8ebc0b" + }, + "generator": { + "path": "tools/web/generate-wbv2-mesh-topology-receipt.mjs", + "sha256": "7c420d6be867d93a51e3049e1dcd52760ca9e0bd7e61ab13d0fe249714cf3f00" + }, + "report": { + "path": "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json", + "sha256": "5828fdde15d73bb1fb066bb05c35762f21471c1f52277903d39b4bdcc020f5f8" + }, + "status": { + "path": "docs/status/WBV2-P11-001.md", + "sha256": "da471d0e7133f0b0f373551c0316c2ddd93505b3510822c4ee5c9256575d4e4d" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P11-001/module-expansion-task-plan.json", + "sha256": "909447163efc1ea0b015a68e838ae9e87e9a8867be008ae16e34349c2dcad650" + }, + "taskContext": { + "path": "tests/golden/WBV2-P11-001/task-context.json", + "sha256": "871e8c6823333927399e60a55cc067b3b535274fc7c7b2911055a69d419b5057" + } + }, + "assertions": { + "operations": 6, + "mainMutations": 6, + "saveReopenExact": 6, + "negativeCases": 3, + "deterministic": true, + "compiledWasmEngine": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P11-002" +} diff --git a/tests/golden/WBV2-P11-001/mesh-topology-production.json b/tests/golden/WBV2-P11-001/mesh-topology-production.json new file mode 100644 index 000000000..ad5234b5f --- /dev/null +++ b/tests/golden/WBV2-P11-001/mesh-topology-production.json @@ -0,0 +1,234 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-001", + "operation": "MESH_TOPOLOGY_OPERATION_FAMILY_CHROMIUM", + "browser": "chromium", + "queueMutation": false, + "sourceSha256": "1a9a894c4106d73a4533485d9fdddfe2883f75e4692b8e53dc174308e12fe60b", + "operations": [ + { + "operation": "MERGE", + "meshId": "mesh:WBV2P2003MergeMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 3, + "edgeCount": 3, + "faceCount": 1, + "triangleCount": 1, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 3, + "edgeCount": 3, + "faceCount": 1, + "triangleCount": 1, + "topology": "triangles" + }, + "savedSha256": "583eb52bb607ec7910dc4b00e403be74341564201ff0522af912fa55ffe912d0", + "exactSaveReopen": true + }, + { + "operation": "DISSOLVE", + "meshId": "mesh:WBV2P2003DissolveMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "savedSha256": "73a4fda59b7be0f28be0741648e199271b1c4871dc86f8d9ee1f908a41aefe19", + "exactSaveReopen": true + }, + { + "operation": "EXTRUDE", + "meshId": "mesh:WBV2P2003ExtrudeMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 6, + "triangleCount": 12, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 6, + "triangleCount": 12, + "topology": "triangles" + }, + "savedSha256": "83f00934ea121a97d5f7734d21abf37d9bd00959f4111bf500efa638b1c9eb91", + "exactSaveReopen": true + }, + { + "operation": "INSET", + "meshId": "mesh:WBV2P2003InsetMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 5, + "triangleCount": 10, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 5, + "triangleCount": 10, + "topology": "triangles" + }, + "savedSha256": "b9f128067f55a42e03b5398057b365f7d4d228a0a31701d764440f16d3173d3a", + "exactSaveReopen": true + }, + { + "operation": "BEVEL", + "meshId": "mesh:WBV2P2003BevelMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "savedSha256": "3d6cc74ebc21375978e0def473a433f59123dff276c98355db981e990784e412", + "exactSaveReopen": true + }, + { + "operation": "LOOP_CUT", + "meshId": "mesh:WBV2P2003LoopCutMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 5, + "edgeCount": 5, + "faceCount": 1, + "triangleCount": 3, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 5, + "edgeCount": 5, + "faceCount": 1, + "triangleCount": 3, + "topology": "triangles" + }, + "savedSha256": "b4f83a7cdc4d2f6322d7abf3530b8855155f2c028fce643d6a73281ccf2148c3", + "exactSaveReopen": true + } + ], + "negative": { + "invalidSelection": { + "code": "INVALID_ARGUMENT", + "message": "meshEdit contains an invalid selection mode or element index" + }, + "incompatible": { + "code": "INVALID_ARGUMENT", + "message": "MESH_EDIT_CONFIGURATION_UNSUPPORTED: operation and selection mode are incompatible" + }, + "stale": { + "code": "INVALID_ARGUMENT", + "message": "REVISION_CONFLICT: command base revision does not match the current SceneIR" + }, + "before": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "revisionBefore": 1, + "revisionAfter": 1 + } +} diff --git a/tests/golden/WBV2-P11-001/mesh-topology-production.second.json b/tests/golden/WBV2-P11-001/mesh-topology-production.second.json new file mode 100644 index 000000000..ad5234b5f --- /dev/null +++ b/tests/golden/WBV2-P11-001/mesh-topology-production.second.json @@ -0,0 +1,234 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-001", + "operation": "MESH_TOPOLOGY_OPERATION_FAMILY_CHROMIUM", + "browser": "chromium", + "queueMutation": false, + "sourceSha256": "1a9a894c4106d73a4533485d9fdddfe2883f75e4692b8e53dc174308e12fe60b", + "operations": [ + { + "operation": "MERGE", + "meshId": "mesh:WBV2P2003MergeMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 3, + "edgeCount": 3, + "faceCount": 1, + "triangleCount": 1, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 3, + "edgeCount": 3, + "faceCount": 1, + "triangleCount": 1, + "topology": "triangles" + }, + "savedSha256": "583eb52bb607ec7910dc4b00e403be74341564201ff0522af912fa55ffe912d0", + "exactSaveReopen": true + }, + { + "operation": "DISSOLVE", + "meshId": "mesh:WBV2P2003DissolveMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "savedSha256": "73a4fda59b7be0f28be0741648e199271b1c4871dc86f8d9ee1f908a41aefe19", + "exactSaveReopen": true + }, + { + "operation": "EXTRUDE", + "meshId": "mesh:WBV2P2003ExtrudeMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 6, + "triangleCount": 12, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 6, + "triangleCount": 12, + "topology": "triangles" + }, + "savedSha256": "83f00934ea121a97d5f7734d21abf37d9bd00959f4111bf500efa638b1c9eb91", + "exactSaveReopen": true + }, + { + "operation": "INSET", + "meshId": "mesh:WBV2P2003InsetMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 5, + "triangleCount": 10, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 5, + "triangleCount": 10, + "topology": "triangles" + }, + "savedSha256": "b9f128067f55a42e03b5398057b365f7d4d228a0a31701d764440f16d3173d3a", + "exactSaveReopen": true + }, + { + "operation": "BEVEL", + "meshId": "mesh:WBV2P2003BevelMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "savedSha256": "3d6cc74ebc21375978e0def473a433f59123dff276c98355db981e990784e412", + "exactSaveReopen": true + }, + { + "operation": "LOOP_CUT", + "meshId": "mesh:WBV2P2003LoopCutMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 5, + "edgeCount": 5, + "faceCount": 1, + "triangleCount": 3, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 5, + "edgeCount": 5, + "faceCount": 1, + "triangleCount": 3, + "topology": "triangles" + }, + "savedSha256": "b4f83a7cdc4d2f6322d7abf3530b8855155f2c028fce643d6a73281ccf2148c3", + "exactSaveReopen": true + } + ], + "negative": { + "invalidSelection": { + "code": "INVALID_ARGUMENT", + "message": "meshEdit contains an invalid selection mode or element index" + }, + "incompatible": { + "code": "INVALID_ARGUMENT", + "message": "MESH_EDIT_CONFIGURATION_UNSUPPORTED: operation and selection mode are incompatible" + }, + "stale": { + "code": "INVALID_ARGUMENT", + "message": "REVISION_CONFLICT: command base revision does not match the current SceneIR" + }, + "before": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "revisionBefore": 1, + "revisionAfter": 1 + } +} diff --git a/tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json b/tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json new file mode 100644 index 000000000..cd9d1cc8d --- /dev/null +++ b/tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json @@ -0,0 +1,245 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-001", + "operation": "MESH_TOPOLOGY_OPERATION_FAMILY_RECEIPT", + "status": "PASS", + "browser": "chromium", + "queueMutation": false, + "source": { + "task": "WBV2-P2-003", + "manifest": "tests/golden/WBV2-P2-003/manifest.json", + "manifestSha256": "79ebc20719fef2b60a3457bca25dac98e755a2f2c1bd3c35361527509a91a987", + "report": "tests/golden/WBV2-P2-003/mesh-edit-report.json", + "reportSha256": "f8bd2ced2e1345248d4b536ef045bb9446a55ca5ae87d834f38904b86521b11d", + "desktopExact": true, + "wasmExact": true, + "sourceSaveReopenExact": true + }, + "production": { + "report": "tests/golden/WBV2-P11-001/mesh-topology-production.json", + "reportSha256": "206e30ba61dc169364f6279464f98afd4885390a155e5de2f4e3de3990d5896d", + "secondReport": "tests/golden/WBV2-P11-001/mesh-topology-production.second.json", + "secondReportSha256": "206e30ba61dc169364f6279464f98afd4885390a155e5de2f4e3de3990d5896d", + "deterministic": true, + "operations": [ + { + "operation": "MERGE", + "meshId": "mesh:WBV2P2003MergeMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 3, + "edgeCount": 3, + "faceCount": 1, + "triangleCount": 1, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003MergeMesh", + "vertexCount": 3, + "edgeCount": 3, + "faceCount": 1, + "triangleCount": 1, + "topology": "triangles" + }, + "exactSaveReopen": true, + "savedSha256": "583eb52bb607ec7910dc4b00e403be74341564201ff0522af912fa55ffe912d0" + }, + { + "operation": "DISSOLVE", + "meshId": "mesh:WBV2P2003DissolveMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003DissolveMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "exactSaveReopen": true, + "savedSha256": "73a4fda59b7be0f28be0741648e199271b1c4871dc86f8d9ee1f908a41aefe19" + }, + { + "operation": "EXTRUDE", + "meshId": "mesh:WBV2P2003ExtrudeMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 6, + "triangleCount": 12, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003ExtrudeMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 6, + "triangleCount": 12, + "topology": "triangles" + }, + "exactSaveReopen": true, + "savedSha256": "83f00934ea121a97d5f7734d21abf37d9bd00959f4111bf500efa638b1c9eb91" + }, + { + "operation": "INSET", + "meshId": "mesh:WBV2P2003InsetMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 5, + "triangleCount": 10, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003InsetMesh", + "vertexCount": 8, + "edgeCount": 12, + "faceCount": 5, + "triangleCount": 10, + "topology": "triangles" + }, + "exactSaveReopen": true, + "savedSha256": "b9f128067f55a42e03b5398057b365f7d4d228a0a31701d764440f16d3173d3a" + }, + { + "operation": "BEVEL", + "meshId": "mesh:WBV2P2003BevelMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003BevelMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "exactSaveReopen": true, + "savedSha256": "3d6cc74ebc21375978e0def473a433f59123dff276c98355db981e990784e412" + }, + { + "operation": "LOOP_CUT", + "meshId": "mesh:WBV2P2003LoopCutMesh", + "baseRevision": 1, + "afterRevision": 2, + "before": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 4, + "edgeCount": 4, + "faceCount": 1, + "triangleCount": 2, + "topology": "triangles" + }, + "after": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 5, + "edgeCount": 5, + "faceCount": 1, + "triangleCount": 3, + "topology": "triangles" + }, + "reopened": { + "id": "mesh:WBV2P2003LoopCutMesh", + "vertexCount": 5, + "edgeCount": 5, + "faceCount": 1, + "triangleCount": 3, + "topology": "triangles" + }, + "exactSaveReopen": true, + "savedSha256": "b4f83a7cdc4d2f6322d7abf3530b8855155f2c028fce643d6a73281ccf2148c3" + } + ], + "negative": { + "invalidSelection": { + "code": "INVALID_ARGUMENT", + "message": "meshEdit contains an invalid selection mode or element index" + }, + "incompatibleConfiguration": { + "code": "INVALID_ARGUMENT", + "message": "MESH_EDIT_CONFIGURATION_UNSUPPORTED: operation and selection mode are incompatible" + }, + "staleRevision": { + "code": "INVALID_ARGUMENT", + "message": "REVISION_CONFLICT: command base revision does not match the current SceneIR" + }, + "revisionPreserved": true + } + }, + "assertions": { + "operations": 6, + "mainMutations": 6, + "revisionDeltaPerOperation": 1, + "saveReopenExact": 6, + "negativeCases": 3, + "negativeMainMutation": false, + "compiledWasmEngine": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P11-002" +} diff --git a/tests/golden/WBV2-P11-001/module-expansion-task-plan.json b/tests/golden/WBV2-P11-001/module-expansion-task-plan.json new file mode 100644 index 000000000..8fef6e381 --- /dev/null +++ b/tests/golden/WBV2-P11-001/module-expansion-task-plan.json @@ -0,0 +1,1716 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_MODULE_EXPANSION_EPOCH_1", + "status": "ACTIVE_MODULE_EXPANSION_QUEUE", + "authority": "queue_reactivated_after_p10_engine_matrix", + "productContract": "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "sourcePlan": "docs/BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "correctiveCheckpoint": { + "task": "C6-003", + "handoff": "tests/golden/corrective/C6-003/handoff.json", + "status": "active", + "blocker": null, + "queueMutation": true, + "legacyTask": "M16-GAP-00277", + "legacyParentNextTask": "M16-GAP-00277" + }, + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "storage": [ + "opfs", + "indexeddb" + ], + "queueMutation": "enabled_after_owner_review_and_g5" + }, + "completionClasses": [ + "LOCAL_EXACT", + "LOCAL_BOUNDED", + "SERVER_EXACT", + "EXCLUDED" + ], + "gates": [ + { + "id": "G0", + "name": "scope_and_inventory", + "requires": [ + "contract", + "inventory", + "capability_matrix" + ] + }, + { + "id": "G1", + "name": "runtime_foundation", + "requires": [ + "sceneir", + "main_transaction", + "worker_lifecycle", + "storage_journal" + ] + }, + { + "id": "G2", + "name": "feature_parity", + "requires": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence" + ] + }, + { + "id": "G3", + "name": "recovery_and_security", + "requires": [ + "cancel", + "restart", + "oom_quota", + "malformed", + "dispose" + ] + }, + { + "id": "G4", + "name": "release_candidate", + "requires": [ + "offline", + "ci", + "sbom", + "rollback", + "hashes" + ] + }, + { + "id": "G5", + "name": "queue_mutation", + "requires": [ + "owner_review", + "protected_hashes", + "handoff", + "single_ready_task" + ] + } + ], + "waves": [ + { + "id": "P0", + "name": "facts_and_contracts", + "gate": "G0", + "tasks": [ + "WBV2-P0-001", + "WBV2-P0-002", + "WBV2-P0-003" + ] + }, + { + "id": "P1", + "name": "runtime_foundation", + "gate": "G1", + "tasks": [ + "WBV2-P1-001", + "WBV2-P1-002", + "WBV2-P1-003", + "WBV2-P1-004", + "WBV2-P1-005" + ] + }, + { + "id": "P2", + "name": "core_modeler_loop", + "gate": "G2", + "tasks": [ + "WBV2-P2-001", + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P2-005" + ] + }, + { + "id": "P3", + "name": "authoring_and_io", + "gate": "G2", + "tasks": [ + "WBV2-P3-001", + "WBV2-P3-002", + "WBV2-P3-003", + "WBV2-P3-004", + "WBV2-P3-005" + ] + }, + { + "id": "P4", + "name": "advanced_local_slices", + "gate": "G2", + "tasks": [ + "WBV2-P4-001", + "WBV2-P4-002", + "WBV2-P4-003", + "WBV2-P4-004" + ] + }, + { + "id": "P5", + "name": "render_and_server", + "gate": "G3", + "tasks": [ + "WBV2-P5-001", + "WBV2-P5-002", + "WBV2-P5-003" + ] + }, + { + "id": "P6", + "name": "security_performance_release", + "gate": "G4", + "tasks": [ + "WBV2-P6-001", + "WBV2-P6-002", + "WBV2-P6-003" + ] + }, + { + "id": "P7", + "name": "full_parity_gap_program", + "gate": "G5", + "tasks": [ + "WBV2-P7-001", + "WBV2-P7-002", + "WBV2-P7-003" + ] + } + ], + "taskContract": { + "onePrimaryBehavior": true, + "requiredEvidence": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence", + "manifest", + "status" + ], + "requiredCommands": [ + "focused", + "determinism", + "hash", + "governance" + ], + "failureState": "in_progress_or_blocked", + "successorRule": "only_from_parent_manifest_nextTask" + }, + "tasks": [ + { + "id": "WBV2-P0-001", + "phase": "P0", + "title": "reconcile_scope_and_checkpoints", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-governance", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-001.md", + "behavior": "Freeze V1/full-parity boundary and reconcile legacy/corrective pointers without queue mutation.", + "outputs": [ + "scope decision", + "checkpoint report", + "protected hash set" + ], + "acceptance": [ + "corrective owner-review status is explicit", + "legacy parent pointer is unchanged", + "plan has one activation gate" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-002", + "phase": "P0", + "title": "generate_blender52_inventory_and_parity_map", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-inventory", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-002.md", + "behavior": "Generate stable Blender 5.2 data-block/operator/editor/node/format inventory and map every entry to a completion class.", + "outputs": [ + "inventory", + "parity map", + "source hash" + ], + "acceptance": [ + "unknown entries are classified", + "inventory is deterministic", + "no entry claims feature parity without evidence" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-003", + "phase": "P0", + "title": "freeze_capability_error_budget_contract", + "kind": "enabling", + "owner": "PROTOCOL", + "dependsOn": [ + "WBV2-P0-001", + "WBV2-P0-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-contract", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-003.md", + "behavior": "Freeze capability levels, stable error codes, revision, budget, cancellation and loss-report schemas.", + "outputs": [ + "versioned protocol", + "capability matrix", + "negative matrix" + ], + "acceptance": [ + "unsupported input fails closed", + "schema hashes are stable", + "migration policy preserves unknown data" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-001", + "phase": "P1", + "title": "stabilize_runtime_variants_and_source_receipts", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P0-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-runtime", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-001.md", + "behavior": "Bind single-thread/pthread WebEngine variants to pinned Blender source/build/runtime receipts.", + "outputs": [ + "runtime manifest", + "variant selector", + "fallback report" + ], + "acceptance": [ + "variant fallback is deterministic", + "source/build hash is verified", + "one engine session has one generation" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-002", + "phase": "P1", + "title": "unify_sceneir_stable_ids_and_binary_deltas", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-001" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-sceneir", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-002.md", + "behavior": "Make SceneIR/WBG1 stable IDs, topology/attribute domains and binary/range deltas canonical across desktop and WASM.", + "outputs": [ + "SceneIR schema", + "binary fixture", + "delta comparator" + ], + "acceptance": [ + "IDs survive save/reopen", + "malformed chunk is rejected", + "desktop and WASM canonical hashes match" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-003", + "phase": "P1", + "title": "unify_main_transaction_history_and_save", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-002" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-history", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-003.md", + "behavior": "Use one Main transaction/revision/history contract for commit, undo/redo, atomic save and reopen.", + "outputs": [ + "transaction contract", + "history receipt", + "save/reopen runner" + ], + "acceptance": [ + "failed/no-op commands add no history", + "stale revision cannot commit", + "reopen state is byte/hash stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-004", + "phase": "P1", + "title": "harden_worker_cancel_restart_and_dispose", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P1-001", + "WBV2-P1-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-lifecycle", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-004.md", + "behavior": "Make cancellation, late-result rejection, Worker restart and resource disposal common to all domains.", + "outputs": [ + "lifecycle runner", + "fault report", + "dispose counters" + ], + "acceptance": [ + "cancel never publishes result", + "generation mismatch is rejected", + "CPU/WASM/GPU owners return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-005", + "phase": "P1", + "title": "harden_opfs_indexeddb_journal_recovery", + "kind": "enabling", + "owner": "STORAGE", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P1-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-storage", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-005.md", + "behavior": "Unify OPFS staging/content addressing and IndexedDB metadata/journal recovery.", + "outputs": [ + "storage schema", + "crash fixtures", + "recovery checker" + ], + "acceptance": [ + "interrupted commit leaves old project usable", + "hash mismatch quarantines payload", + "small project recovers after restart" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-001", + "phase": "P2", + "title": "open_blend_scene_context_and_outliner", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P1-005" + ], + "parityId": "EDITOR.OPEN_SCENE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-editor", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-001.md", + "behavior": "Open a minimal .blend and expose scene/object/collection context from authoritative Main.", + "outputs": [ + "desktop fixture", + "outliner report", + "Chromium path" + ], + "acceptance": [ + "stable IDs and selection revision match", + "missing data is structured", + "reopen preserves context" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-002", + "phase": "P2", + "title": "object_collection_parent_transform_workflow", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P2-001" + ], + "parityId": "OBJECT.TRANSFORM_HIERARCHY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-scene", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-002.md", + "behavior": "Edit object transform, collection membership and parent hierarchy through Main transactions.", + "outputs": [ + "desktop/WASM golden", + "negative cases", + "save/reopen receipt" + ], + "acceptance": [ + "world matrix parity", + "cycle/locked/library edits reject", + "undo/redo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-003", + "phase": "P2", + "title": "mesh_edit_core_operations", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P2-002" + ], + "parityId": "MESH.EDIT_CORE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-mesh", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-003.md", + "behavior": "Expose bounded vertex/edge/face selection plus merge/dissolve/extrude/inset/bevel/loop-cut.", + "outputs": [ + "Blender fixture set", + "topology comparator", + "Chromium edit path" + ], + "acceptance": [ + "topology/attributes match", + "invalid selection and budget fail closed", + "single transaction and reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-004", + "phase": "P2", + "title": "dual_viewport_sceneir_render_path", + "kind": "feature", + "owner": "VIEWPORT", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P2-003" + ], + "parityId": "VIEWPORT.MAIN_OFFSCREEN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-viewport", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-004.md", + "behavior": "Render the same validated SceneIR through main-thread WebGL2 and OffscreenCanvas Worker paths.", + "outputs": [ + "pixel report", + "viewport diagnostics", + "device recovery" + ], + "acceptance": [ + "both paths have nonblank pixels", + "selection/camera revision is shared", + "device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-005", + "phase": "P2", + "title": "close_p0_user_loop", + "kind": "feature", + "owner": "INTEGRATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P1-005", + "WBV2-P2-004" + ], + "parityId": "WORKFLOW.P0_USER_LOOP", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-integration", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-005.md", + "behavior": "Prove open -> edit -> undo -> redo -> save -> restart -> reopen -> GLB in one production flow.", + "outputs": [ + "P0 workflow report", + "release binding", + "rollback receipt" + ], + "acceptance": [ + "Main revision and exported asset are bound", + "fault/cancel leaves old state", + "Chromium production path passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-001", + "phase": "P3", + "title": "material_uv_principled_asset_workflow", + "kind": "feature", + "owner": "MATERIAL", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005" + ], + "parityId": "MATERIAL.PBR_UV", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-001.md", + "behavior": "Edit material slots, UVs and declared Principled/Image/Normal graph nodes with content-addressed textures.", + "outputs": [ + "material golden", + "texture receipt", + "loss report" + ], + "acceptance": [ + "desktop/WASM node fields match", + "unsupported node retained/blocked", + "packed asset survives reopen" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-002", + "phase": "P3", + "title": "keyframe_timeline_action_workflow", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-005", + "WBV2-P3-001" + ], + "parityId": "ANIMATION.TRS_ACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-002.md", + "behavior": "Create/edit TRS keyframes, timeline and declared Action interpolation through Main.", + "outputs": [ + "frame golden", + "animation comparator", + "reopen report" + ], + "acceptance": [ + "sampled values and handles match", + "stale frame result rejected", + "undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-003", + "phase": "P3", + "title": "armature_pose_constraint_skin_workflow", + "kind": "feature", + "owner": "RIG", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P3-002" + ], + "parityId": "RIG.POSE_SKIN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-rig", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-003.md", + "behavior": "Read and edit declared armature pose/constraint/weight/shape-key slices with bounded evaluation.", + "outputs": [ + "pose golden", + "skin report", + "unsupported matrix" + ], + "acceptance": [ + "pose matrices and weights match", + "unsupported constraint is explicit", + "save/reopen and small recovery pass" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-004", + "phase": "P3", + "title": "glb_roundtrip_and_loss_report", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P2-005", + "WBV2-P3-001", + "WBV2-P3-003" + ], + "parityId": "IO.GLB_ROUNDTRIP", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-io", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-004.md", + "behavior": "Import/export declared GLB mesh/PBR/texture/morph/skin/animation and report non-mapped semantics.", + "outputs": [ + "GLB fixtures", + "desktop reimport report", + "loss report" + ], + "acceptance": [ + "roundtrip canonical graph matches", + "sparse/external URI/budget negatives reject", + "no silent loss" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-005", + "phase": "P3", + "title": "library_asset_append_link_override", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P2-001", + "WBV2-P3-004" + ], + "parityId": "ASSET.LIBRARY_OPERATIONS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-assets", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-005.md", + "behavior": "Support declared append/link/override ownership, reload and missing-library semantics.", + "outputs": [ + "library fixtures", + "ownership report", + "negative matrix" + ], + "acceptance": [ + "source/hash/owner identity preserved", + "linked mutation blocked", + "stale generation and missing source fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-001", + "phase": "P4", + "title": "modifier_graph_and_apply_slices", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005", + "WBV2-P3-005" + ], + "parityId": "MODIFIER.DECLARED_SLICES", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-001.md", + "behavior": "Enable one declared modifier parameter/apply workflow at a time with dependency-aware blocking.", + "outputs": [ + "modifier goldens", + "dependency report", + "negative cases" + ], + "acceptance": [ + "desktop/evaluated Main match", + "unknown modifier retained and blocked", + "apply/undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-002", + "phase": "P4", + "title": "geometry_nodes_and_shader_allowlist", + "kind": "feature", + "owner": "NODES", + "dependsOn": [ + "WBV2-P3-001", + "WBV2-P4-001" + ], + "parityId": "NODES.ALLOWLIST", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-002.md", + "behavior": "Read/write/evaluate only declared Geometry Nodes and shader graph allowlists with resource budgets.", + "outputs": [ + "node fixtures", + "compile/cache receipts", + "unsupported graph reports" + ], + "acceptance": [ + "node/socket/link/default parity", + "budget and unknown-node block before commit", + "compile failure rolls back" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-003", + "phase": "P4", + "title": "sculpt_nonmesh_and_paint_bounded_slices", + "kind": "feature", + "owner": "SCULPT", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P4-002" + ], + "parityId": "SCULPT.NONMESH.PAINT_BOUNDED", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-003.md", + "behavior": "Expose declared sculpt attributes/strokes, Curve/Surface/Font/PointCloud and paint slices with explicit PBVH limits.", + "outputs": [ + "non-mesh fixtures", + "stroke report", + "capability blocks" + ], + "acceptance": [ + "Main commit is atomic", + "unsupported brush/solver returns stable code", + "GPU/OOM/restart recovery passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-004", + "phase": "P4", + "title": "simulation_cache_identity_and_lifecycle", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P4-002", + "WBV2-P4-003" + ], + "parityId": "SIMULATION.CACHE_LIFECYCLE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G3", + "card": "docs/tasks/WBV2-P4-004.md", + "behavior": "Bind declared simulation cache to source/settings/revision hashes with cancellation, LRU and restart recovery.", + "outputs": [ + "cache fixtures", + "identity report", + "quarantine evidence" + ], + "acceptance": [ + "stale/corrupt cache never publishes", + "small cache recovers after restart", + "budget release is observable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-001", + "phase": "P5", + "title": "render_capability_routing", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P2-004", + "WBV2-P4-002", + "WBV2-P4-004" + ], + "parityId": "RENDER.ROUTING", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-001.md", + "behavior": "Route bounded Eevee/WebGL capabilities locally and unsupported render classes to SERVER_EXACT or EXCLUDED.", + "outputs": [ + "render receipts", + "pixel golden", + "routing report" + ], + "acceptance": [ + "source/settings/build identity bound", + "unsupported route cannot pretend local success", + "cancel/device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-002", + "phase": "P5", + "title": "compositor_sequencer_media_recovery", + "kind": "feature", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P3-002", + "WBV2-P5-001" + ], + "parityId": "MEDIA.BOUNDED_WORKFLOW", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-002.md", + "behavior": "Provide declared compositor/sequencer/codec/proxy/audio slices with revision and recovery gates.", + "outputs": [ + "media receipts", + "recovery report", + "audio/session diagnostics" + ], + "acceptance": [ + "seek/decode revision ordering", + "cancel/timeout does not publish", + "quota/OOM/restart leaves project valid" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-003", + "phase": "P5", + "title": "server_job_result_binding", + "kind": "feature", + "owner": "SERVER", + "dependsOn": [ + "WBV2-P0-003", + "WBV2-P5-001", + "WBV2-P5-002" + ], + "parityId": "SERVER.JOB_BINDING", + "implementationClass": "SERVER_EXACT", + "parallelGroup": "p5-server", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-003.md", + "behavior": "Bind server render/encode/physics jobs to immutable input/settings/build/output hashes and explicit lifecycle states.", + "outputs": [ + "server protocol", + "idempotency receipt", + "negative matrix" + ], + "acceptance": [ + "duplicate request is idempotent", + "stale result cannot bind", + "timeout/cancel/OOM produces no READY output" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-001", + "phase": "P6", + "title": "scripting_default_deny_and_audit", + "kind": "feature", + "owner": "SECURITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P5-003" + ], + "parityId": "SECURITY.SCRIPTING", + "implementationClass": "EXCLUDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-001.md", + "behavior": "Read text/metadata and expose audited, budgeted, default-deny script policy without arbitrary execution.", + "outputs": [ + "policy manifest", + "malicious fixtures", + "audit report" + ], + "acceptance": [ + "autorun/network/add-on defaults deny", + "sandbox cancellation/dispose works", + "no secret or filesystem escape" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-002", + "phase": "P6", + "title": "performance_fault_and_recovery_matrix", + "kind": "enabling", + "owner": "RELIABILITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P1-005", + "WBV2-P2-004", + "WBV2-P6-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-002.md", + "behavior": "Run deterministic geometry/texture/media/cache budgets and inject OOM/quota/device/network faults.", + "outputs": [ + "budget matrix", + "fault reports", + "resource release ledger" + ], + "acceptance": [ + "100k/1M/10M thresholds recorded", + "fault leaves old revision usable", + "all owned resources return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-003", + "phase": "P6", + "title": "offline_ci_sbom_and_rollback_release", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P6-001", + "WBV2-P6-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-release", + "gate": "G4", + "card": "docs/tasks/WBV2-P6-003.md", + "behavior": "Produce reproducible offline/source/binary release packages with CI lanes, SBOM and rollback evidence.", + "outputs": [ + "RC manifest", + "offline archive", + "CI reports" + ], + "acceptance": [ + "quick/Chromium/release lanes pass", + "artifact hashes reproduce", + "upgrade/rollback and known limitations are tested" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-001", + "phase": "P7", + "title": "cluster_full_blender_gap_inventory", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-002", + "WBV2-P6-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-001.md", + "behavior": "Cluster remaining Blender 5.2 data-block/operator/editor/node/format gaps by family and evidence class.", + "outputs": [ + "cluster catalog", + "coverage report", + "risk ranking" + ], + "acceptance": [ + "each gap has stable ID and owner", + "negative-only/unsupported is not positive parity", + "clusters are deterministic" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-002", + "phase": "P7", + "title": "generate_atomic_family_gap_queue", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-002.md", + "behavior": "Generate one task per parityId x observable behavior x implementation class with parent/hash context.", + "outputs": [ + "task index", + "task catalog", + "task cards" + ], + "acceptance": [ + "one active ready task", + "no guessed successor", + "each card fits context budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-003", + "phase": "P7", + "title": "full_parity_candidate_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P7-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P7-003.md", + "behavior": "Recompute parity closure, evidence health, recovery health and release decision from machine manifests.", + "outputs": [ + "parity release report", + "known limitations", + "final decision" + ], + "acceptance": [ + "all claims bind to evidence", + "blocked/excluded/server classes remain explicit", + "queue and protected hashes pass" + ], + "status": "blocked", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-000", + "phase": "P8", + "title": "authorize_recovery_capability_root", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-000.md", + "behavior": "Authorize a recovery epoch without rewriting the blocked P7 manifest.", + "outputs": [ + "recovery plan", + "root manifest", + "queue authorization" + ], + "acceptance": [ + "P7 evidence remains hash exact", + "recovery scope is explicit", + "one recovery task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P8-001", + "phase": "P8", + "title": "rebaseline_mutable_inventories", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-001.md", + "behavior": "Rebaseline mutable WBV2 plan and dependency inventory inputs while preserving historical manifests.", + "outputs": [ + "semantic drift report", + "current inventory baseline", + "manifest" + ], + "acceptance": [ + "only expected mutable hashes drift", + "dependency closure is unchanged", + "historical manifests remain unmodified" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-002", + "phase": "P8", + "title": "close_atomic_chromium_receipts", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P8-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-receipts", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-002.md", + "behavior": "Produce and bind all 45 atomic Chromium family receipts.", + "outputs": [ + "Chromium report", + "45 receipt index", + "receipt manifests" + ], + "acceptance": [ + "45 receipts are manifest-bound", + "desktop/WASM/save-reopen behaviors are explicit", + "Chromium is the only browser" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-003", + "phase": "P8", + "title": "authorize_m12_provenance_epoch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-provenance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-003.md", + "behavior": "Bind restored M12 sources and explicitly rebaseline unavailable originals in a new provenance epoch.", + "outputs": [ + "provenance epoch", + "replacement bindings", + "manifest" + ], + "acceptance": [ + "22 restored originals stay exact", + "62 unavailable entries are not called restored", + "all replacements are hash-bound" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-004", + "phase": "P8", + "title": "recompute_recovery_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P8-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-004.md", + "behavior": "Recompute the release decision from the recovery epoch and atomic receipts.", + "outputs": [ + "release gate", + "known limitations", + "final manifest" + ], + "acceptance": [ + "all receipts bind to manifests", + "provenance epoch is explicit", + "all governance gates pass" + ], + "status": "in_progress", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-000", + "phase": "P9", + "title": "authorize_feature_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-000.md", + "behavior": "Authorize feature parity continuation after provenance epoch 2 without claiming historical byte reproduction.", + "outputs": [ + "continuation receipt", + "feature parity plan", + "scope limits" + ], + "acceptance": [ + "P8 provenance evidence remains exact", + "authorized baseline is explicit", + "one feature task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P9-001", + "phase": "P9", + "title": "mesh_production_chromium_receipt", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P9-000" + ], + "parityId": "CAP-MESH-POSITIVE-EDIT", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-mesh", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-001.md", + "behavior": "Bind the existing Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt.", + "outputs": [ + "Chromium mesh receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real meshTranslateVertex command passes", + "desktop/WASM delta matches", + "save/reopen is exact", + "malformed/stale/unknown inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-002", + "phase": "P9", + "title": "modifier_production_chromium_receipt", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P9-001" + ], + "parityId": "CAP-MODIFIER-STATE-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-modifier", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-002.md", + "behavior": "Bind the existing Modifier Main transaction to a production Chromium receipt.", + "outputs": [ + "Chromium modifier receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real modifierSetEnabled command passes", + "desktop/WASM delta matches", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-003", + "phase": "P9", + "title": "asset_catalog_production_chromium_receipt", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P9-002" + ], + "parityId": "CAP-ASSET-CATALOG-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-asset", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-003.md", + "behavior": "Bind the existing Asset Catalog Main transaction and resource resolver to a production Chromium receipt.", + "outputs": [ + "Chromium asset receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real assetCatalogAppend command passes", + "resource hash is bound", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-004", + "phase": "P9", + "title": "recompute_feature_parity_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P9-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-release", + "gate": "G7", + "card": "docs/tasks/WBV2-P9-004.md", + "behavior": "Recompute declared feature parity claims from production Chromium receipts and authorized provenance.", + "outputs": [ + "feature parity gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only evidenced feature claims are emitted", + "authorized baseline remains explicit", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-000", + "phase": "P10", + "title": "authorize_native_engine_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P9-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-000.md", + "behavior": "Authorize native Blender/WASM engine parity continuation after bounded Chromium capability evidence.", + "outputs": [ + "continuation receipt", + "native parity plan", + "scope limits" + ], + "acceptance": [ + "P9 evidence remains hash-bound", + "native build/runtime is explicit", + "one native parity task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P10-001", + "phase": "P10", + "title": "reconcile_wbv2_inventory_source_drift", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-inventory", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-001.md", + "behavior": "Record the authorized mutable WBV2 plan drift and prove dependency closure stability without rewriting historical P0 evidence.", + "outputs": [ + "current source hash baseline", + "drift report", + "checker compatibility" + ], + "acceptance": [ + "historical P0 hashes remain unchanged", + "only authorized plan drift is recorded", + "dependency roots/lockfile/closure remain stable", + "inventory checker passes using current baseline" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-002", + "phase": "P10", + "title": "bind_native_and_wasm_engine_receipts", + "kind": "feature", + "owner": "ENGINE", + "dependsOn": [ + "WBV2-P10-001" + ], + "parityId": "ENGINE.NATIVE_WASM_BRIDGE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p10-engine", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-002.md", + "behavior": "Bind Mesh, Modifier, and Asset Catalog receipts to the compiled Blender native binary and web_engine.wasm runtime.", + "outputs": [ + "native receipt", + "WASM receipt", + "Chromium engine report" + ], + "acceptance": [ + "native Blender binary is source-bound", + "WASM binary and JS are hash-bound", + "same mutation reaches real engine/Main", + "save/reopen and failures remain exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-003", + "phase": "P10", + "title": "expand_core_module_operator_matrix", + "kind": "feature", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-002" + ], + "parityId": "CORE.MODULE_MATRIX", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-matrix", + "gate": "G7", + "card": "docs/tasks/WBV2-P10-003.md", + "behavior": "Expand the three proven capability modules with data-driven operator coverage and aggregate regression receipts.", + "outputs": [ + "module matrix", + "shard reports", + "aggregate manifest" + ], + "acceptance": [ + "positive cases are L2+", + "negative cases do not mutate Main", + "shards use one catalog hash", + "unmapped and retained-negative cases stay explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-000", + "phase": "P11", + "title": "authorize_module_expansion_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P10-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-governance", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-000.md", + "behavior": "Authorize deeper module production after real native/WASM engine binding and the first aggregate matrix.", + "outputs": [ + "continuation root", + "module expansion plan", + "scope limits" + ], + "acceptance": [ + "P10 evidence remains hash-bound", + "one expansion task is active", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P11-001", + "phase": "P11", + "title": "mesh_topology_operation_family", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P11-000" + ], + "parityId": "MESH.EDIT_TOPOLOGY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-mesh", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-001.md", + "behavior": "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real Blender WASM Main and preserve each result through save/reopen.", + "outputs": [ + "topology receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "six mesh operations mutate Main", + "revision increments exactly once", + "save/reopen preserves topology counts", + "invalid selection and incompatible configuration fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-002", + "phase": "P11", + "title": "modifier_parameter_apply_family", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P11-001" + ], + "parityId": "MODIFIER.PARAMETER_APPLY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-modifier", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-002.md", + "behavior": "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", + "outputs": [ + "modifier parameter receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "parameter mutation is native/WASM bound", + "apply result is evaluated", + "save/reopen is exact", + "dependency and stale inputs fail closed" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-003", + "phase": "P11", + "title": "asset_link_override_reload_family", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P11-002" + ], + "parityId": "ASSET.LINK_OVERRIDE_RELOAD_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-asset", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-003.md", + "behavior": "Extend the real Asset Main path from append to link, override, reload, and missing-library boundaries.", + "outputs": [ + "asset ownership receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "source ownership is preserved", + "override is local and hash-bound", + "reload revision is checked", + "missing source remains explicit" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-004", + "phase": "P11", + "title": "recompute_engine_module_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P11-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-release", + "gate": "G8", + "card": "docs/tasks/WBV2-P11-004.md", + "behavior": "Recompute engine-bound module parity from P10 and P11 receipts without claiming whole-inventory completion.", + "outputs": [ + "engine module gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only engine-bound claims are emitted", + "inventory remainder is explicit", + "provenance epoch 2 remains authorized rebaseline only", + "full historical reproduction remains false" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ], + "parentPlan": { + "path": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "sha256": "0f4750e45f2d1ca7d68faa35743e5b758ea8091f18d1d0e312ab548228d6f782" + }, + "recoveryRoot": "WBV2-P11-000", + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P11-000/module-expansion-task-plan.json", + "sha256": "e1280465871db20dd8952f6f5949971ea5bee57a6191000247ac51b6f28cc39a" + } +} diff --git a/tests/golden/WBV2-P11-001/task-context.json b/tests/golden/WBV2-P11-001/task-context.json new file mode 100644 index 000000000..8b3a46732 --- /dev/null +++ b/tests/golden/WBV2-P11-001/task-context.json @@ -0,0 +1,185 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-001", + "parentTask": "WBV2-P11-000", + "status": "in_progress", + "goal": "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real compiled WebEngine WASM Main and preserve each result through save/reopen.", + "scope": { + "gap": "workflow:mesh_topology_operation_family", + "ownerFamily": "MESH", + "implementationClass": "LOCAL_EXACT" + }, + "commands": [ + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-topology-production.spec.ts", + "node tools/web/generate-wbv2-mesh-topology-receipt.mjs --write", + "node tools/web/check-task-context.mjs --task WBV2-P11-001 --write" + ], + "inputPaths": [ + "tests/golden/WBV2-P2-003/mesh-edit-desktop-report.json" + ], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3428, + "contextRemainingTokens": 856 + }, + "source": { + "bytes": 6476, + "tokens": 1620 + }, + "selected": [ + { + "path": "tests/golden/WBV2-P2-003/mesh-edit-desktop-report.json", + "bytes": 2366, + "tokens": 592 + } + ], + "excluded": [ + { + "path": "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", + "bytes": 88023, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P2-003/mesh-edit-report.json", + "bytes": 2172, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "web/app/src/engine-client/WebEngineClient.ts", + "bytes": 16197, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", + "bytes": 6622, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P11-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P11-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P11-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 1, + "bytes": 2366, + "tokens": 592 + } + }, + "exitCriteria": [ + "six mesh operations mutate Main", + "revision increments exactly once", + "save/reopen preserves topology counts", + "invalid selection and incompatible configuration fail closed" + ], + "nextTask": "WBV2-P11-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P11-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P11-000/manifest.json", + "parentStatus": "docs/status/WBV2-P11-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P11-001.md", + "tests/golden/WBV2-P11-000/manifest.json", + "docs/status/WBV2-P11-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-P11-000", + "parentTask": "WBV2-P10-003", + "status": "done", + "nextTask": "WBV2-P11-001", + "artifactCount": 8 + }, + "statusSummary": [ + "# WBV2-P11-000 status", + "- task: `WBV2-P11-000`; parent: `WBV2-P10-003`; status: `done`", + "- nextTask: `WBV2-P11-001`", + "Module expansion is authorized after P10 bound the compiled Blender native/WASM engine. P11 remains evidence-bound, Chromium-only, and explicit about the inventory remainder and authorized provenance baseline." + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1424, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 36, + "taskTokens": 356 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P11-001.md", + "bytes": 1424, + "lines": 36, + "tokens": 356 + }, + { + "path": "tests/golden/WBV2-P11-000/manifest.json", + "bytes": 1925, + "lines": 56, + "tokens": 482 + }, + { + "path": "docs/status/WBV2-P11-000.md", + "bytes": 324, + "lines": 7, + "tokens": 81 + } + ], + "sourceTokens": 1620, + "evidenceFiles": 1, + "evidenceBytes": 2366, + "evidenceTokens": 592, + "totalTokens": 2212, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 3236, + "serializedContextTokens": 736, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P11-002/manifest.json b/tests/golden/WBV2-P11-002/manifest.json new file mode 100644 index 000000000..b505938ea --- /dev/null +++ b/tests/golden/WBV2-P11-002/manifest.json @@ -0,0 +1,79 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-002", + "parentTask": "WBV2-P11-001", + "operation": "MODIFIER_PARAMETER_APPLY_FAMILY_RECEIPT", + "status": "done", + "enablingTask": false, + "parityStateChange": true, + "runtime": "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P11-001/manifest.json", + "sha256": "e08a02819065f1e7bc72a3bfae99e768c502dfa90af4b0614a701e7cca88b576" + }, + "sourceManifest": { + "path": "tests/golden/WBV2-P4-001/manifest.json", + "sha256": "6f1bee73c987f5e66733feb03d1d708e0f2dbd0776ac6634dbf694cde385143c" + }, + "sourceReport": { + "path": "tests/golden/WBV2-P4-001/modifier-report.json", + "sha256": "65d2cf962511ae181e53cda1cc01f8db46819ee450a470384abbe829d549adf8" + }, + "engineReceipt": { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "sha256": "09c13b1814d61a6132ae1168d999e09b768915fe7fec652b6b965f9a6d3796f9" + }, + "production": { + "path": "tests/golden/WBV2-P11-002/modifier-parameter-production.json", + "sha256": "8ed9e05aa51ad250bff1dd5095f977c9beb883bfa77203d43ba1f54920efee1a" + }, + "productionSecond": { + "path": "tests/golden/WBV2-P11-002/modifier-parameter-production.second.json", + "sha256": "8ed9e05aa51ad250bff1dd5095f977c9beb883bfa77203d43ba1f54920efee1a" + }, + "e2e": { + "path": "web/tests/e2e/wbv2-modifier-parameter-production.spec.ts", + "sha256": "1b6f247367222a5d92511b14cc320732e1eb07e3e1cdfdf90929af507039ee23" + }, + "protocol": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8" + }, + "client": { + "path": "web/app/src/engine-client/WebEngineClient.ts", + "sha256": "f6d9a8e0a16403bc6fb765195b8f1a619a28de7a75c59a412f1654d46e8ebc0b" + }, + "generator": { + "path": "tools/web/generate-wbv2-modifier-parameter-receipt.mjs", + "sha256": "25f2a8ad878fd6fe6bc456f29b3e500f80a47e1a236788e5b37d33f61dc946e1" + }, + "report": { + "path": "tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json", + "sha256": "339bf5007b04f81aecbd03a22791659895b2e78219cd5ee4031b890eb3120bc5" + }, + "status": { + "path": "docs/status/WBV2-P11-002.md", + "sha256": "9ab967a17d3b71d840b7108f306394bbc07c7f0a5ca63f4d0b664cb5c7590bab" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P11-002/module-expansion-task-plan.json", + "sha256": "8593eef68c7c8ba9fe772a37c84d6462d945220f0ebdb21a7cf981bd1f0f3fb0" + }, + "taskContext": { + "path": "tests/golden/WBV2-P11-002/task-context.json", + "sha256": "c5fa4e2865967ade4f8fd6da5e4516cb5574e1a520df5d68fc793be438b3530d" + } + }, + "assertions": { + "parameterMutation": "DECIMATE_COLLAPSE", + "evaluatedApply": true, + "realEngineMainMutation": true, + "saveReopen": "EXACT", + "negativeCases": 2, + "dependencyBlockHandled": true, + "deterministic": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P11-003" +} diff --git a/tests/golden/WBV2-P11-002/modifier-parameter-production.json b/tests/golden/WBV2-P11-002/modifier-parameter-production.json new file mode 100644 index 000000000..f8994120a --- /dev/null +++ b/tests/golden/WBV2-P11-002/modifier-parameter-production.json @@ -0,0 +1,169 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-002", + "operation": "MODIFIER_PARAMETER_APPLY_FAMILY_CHROMIUM", + "browser": "chromium", + "queueMutation": false, + "sourceSha256": "02e56fd6745d983ee9f5ee3f48e581f116f0c41c2d2e7dec062517b4af86718f", + "meshId": "mesh:WBV2P4001ModifierMesh", + "modifierUuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "before": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 8, + "edgeCount": 18, + "faceCount": 12, + "triangleCount": 12, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": true, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": true, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": true, + "evaluationStatus": "BLOCKED" + } + ] + }, + "disabledRevision": 4, + "appliedRevision": 5, + "simplify": { + "schemaVersion": 1, + "status": "applied", + "sourceMeshRevision": 4, + "mode": "COLLAPSE", + "originalFaceCount": 12, + "originalTriangleCount": 12, + "outputFaceCount": 8, + "outputTriangleCount": 8, + "ratio": 0.75, + "evaluatedMeshId": "mesh:WBV2P4001ModifierMesh" + }, + "after": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "afterStale": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "afterMalformed": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "stale": { + "code": "INVALID_ARGUMENT", + "message": "simplify profile sourceMeshRevision is stale" + }, + "malformed": { + "code": "INVALID_ARGUMENT", + "message": "native decimate output failed" + }, + "savedSha256": "a608a881f7da0907efb1262d980a6a1afc6b178ca68664909604fb90a1e34e20", + "reopened": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "exactSaveReopen": true +} diff --git a/tests/golden/WBV2-P11-002/modifier-parameter-production.second.json b/tests/golden/WBV2-P11-002/modifier-parameter-production.second.json new file mode 100644 index 000000000..f8994120a --- /dev/null +++ b/tests/golden/WBV2-P11-002/modifier-parameter-production.second.json @@ -0,0 +1,169 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-002", + "operation": "MODIFIER_PARAMETER_APPLY_FAMILY_CHROMIUM", + "browser": "chromium", + "queueMutation": false, + "sourceSha256": "02e56fd6745d983ee9f5ee3f48e581f116f0c41c2d2e7dec062517b4af86718f", + "meshId": "mesh:WBV2P4001ModifierMesh", + "modifierUuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "before": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 8, + "edgeCount": 18, + "faceCount": 12, + "triangleCount": 12, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": true, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": true, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": true, + "evaluationStatus": "BLOCKED" + } + ] + }, + "disabledRevision": 4, + "appliedRevision": 5, + "simplify": { + "schemaVersion": 1, + "status": "applied", + "sourceMeshRevision": 4, + "mode": "COLLAPSE", + "originalFaceCount": 12, + "originalTriangleCount": 12, + "outputFaceCount": 8, + "outputTriangleCount": 8, + "ratio": 0.75, + "evaluatedMeshId": "mesh:WBV2P4001ModifierMesh" + }, + "after": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "afterStale": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "afterMalformed": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "stale": { + "code": "INVALID_ARGUMENT", + "message": "simplify profile sourceMeshRevision is stale" + }, + "malformed": { + "code": "INVALID_ARGUMENT", + "message": "native decimate output failed" + }, + "savedSha256": "a608a881f7da0907efb1262d980a6a1afc6b178ca68664909604fb90a1e34e20", + "reopened": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "exactSaveReopen": true +} diff --git a/tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json b/tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json new file mode 100644 index 000000000..018542f4d --- /dev/null +++ b/tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json @@ -0,0 +1,142 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-002", + "operation": "MODIFIER_PARAMETER_APPLY_FAMILY_RECEIPT", + "status": "PASS", + "browser": "chromium", + "queueMutation": false, + "source": { + "task": "WBV2-P4-001", + "manifest": "tests/golden/WBV2-P4-001/manifest.json", + "manifestSha256": "6f1bee73c987f5e66733feb03d1d708e0f2dbd0776ac6634dbf694cde385143c", + "report": "tests/golden/WBV2-P4-001/modifier-report.json", + "reportSha256": "65d2cf962511ae181e53cda1cc01f8db46819ee450a470384abbe829d549adf8", + "desktopExact": true, + "wasmExact": true, + "sourceSaveReopenExact": true + }, + "engine": { + "receipt": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "receiptSha256": "09c13b1814d61a6132ae1168d999e09b768915fe7fec652b6b965f9a6d3796f9", + "compiledWasmBound": true, + "realEngineMainMutation": true + }, + "production": { + "report": "tests/golden/WBV2-P11-002/modifier-parameter-production.json", + "reportSha256": "8ed9e05aa51ad250bff1dd5095f977c9beb883bfa77203d43ba1f54920efee1a", + "secondReport": "tests/golden/WBV2-P11-002/modifier-parameter-production.second.json", + "secondReportSha256": "8ed9e05aa51ad250bff1dd5095f977c9beb883bfa77203d43ba1f54920efee1a", + "deterministic": true, + "meshId": "mesh:WBV2P4001ModifierMesh", + "modifierUuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "disabledRevision": 4, + "appliedRevision": 5, + "profile": { + "mode": "COLLAPSE", + "ratio": 0.75, + "attributePolicy": "PRESERVE" + }, + "before": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 8, + "edgeCount": 18, + "faceCount": 12, + "triangleCount": 12, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": true, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": true, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": true, + "evaluationStatus": "BLOCKED" + } + ] + }, + "after": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "reopened": { + "id": "mesh:WBV2P4001ModifierMesh", + "vertexCount": 6, + "edgeCount": 12, + "faceCount": 8, + "triangleCount": 8, + "modifierStack": [ + { + "uuid": "modifier:object:WBV2P4001ModifierObject:1277244409", + "type": "BEVEL", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:559072788", + "type": "DECIMATE", + "enabled": false, + "evaluationStatus": "METADATA_ONLY" + }, + { + "uuid": "modifier:object:WBV2P4001ModifierObject:336849697", + "type": "PARTICLE_SYSTEM", + "enabled": false, + "evaluationStatus": "BLOCKED" + } + ] + }, + "exactSaveReopen": true, + "stale": { + "code": "INVALID_ARGUMENT", + "message": "simplify profile sourceMeshRevision is stale" + }, + "malformed": { + "code": "INVALID_ARGUMENT", + "message": "native decimate output failed" + } + }, + "assertions": { + "parameterMutation": "DECIMATE_COLLAPSE", + "evaluatedApply": true, + "mainMutation": "CHANGED", + "revisionDelta": 1, + "saveReopenExact": true, + "dependencyBlockHandled": true, + "staleProfileRejected": true, + "malformedProfileRejected": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P11-003" +} diff --git a/tests/golden/WBV2-P11-002/module-expansion-task-plan.json b/tests/golden/WBV2-P11-002/module-expansion-task-plan.json new file mode 100644 index 000000000..3aad37ebc --- /dev/null +++ b/tests/golden/WBV2-P11-002/module-expansion-task-plan.json @@ -0,0 +1,1716 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_MODULE_EXPANSION_EPOCH_1", + "status": "ACTIVE_MODULE_EXPANSION_QUEUE", + "authority": "queue_reactivated_after_p10_engine_matrix", + "productContract": "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "sourcePlan": "docs/BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "correctiveCheckpoint": { + "task": "C6-003", + "handoff": "tests/golden/corrective/C6-003/handoff.json", + "status": "active", + "blocker": null, + "queueMutation": true, + "legacyTask": "M16-GAP-00277", + "legacyParentNextTask": "M16-GAP-00277" + }, + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "storage": [ + "opfs", + "indexeddb" + ], + "queueMutation": "enabled_after_owner_review_and_g5" + }, + "completionClasses": [ + "LOCAL_EXACT", + "LOCAL_BOUNDED", + "SERVER_EXACT", + "EXCLUDED" + ], + "gates": [ + { + "id": "G0", + "name": "scope_and_inventory", + "requires": [ + "contract", + "inventory", + "capability_matrix" + ] + }, + { + "id": "G1", + "name": "runtime_foundation", + "requires": [ + "sceneir", + "main_transaction", + "worker_lifecycle", + "storage_journal" + ] + }, + { + "id": "G2", + "name": "feature_parity", + "requires": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence" + ] + }, + { + "id": "G3", + "name": "recovery_and_security", + "requires": [ + "cancel", + "restart", + "oom_quota", + "malformed", + "dispose" + ] + }, + { + "id": "G4", + "name": "release_candidate", + "requires": [ + "offline", + "ci", + "sbom", + "rollback", + "hashes" + ] + }, + { + "id": "G5", + "name": "queue_mutation", + "requires": [ + "owner_review", + "protected_hashes", + "handoff", + "single_ready_task" + ] + } + ], + "waves": [ + { + "id": "P0", + "name": "facts_and_contracts", + "gate": "G0", + "tasks": [ + "WBV2-P0-001", + "WBV2-P0-002", + "WBV2-P0-003" + ] + }, + { + "id": "P1", + "name": "runtime_foundation", + "gate": "G1", + "tasks": [ + "WBV2-P1-001", + "WBV2-P1-002", + "WBV2-P1-003", + "WBV2-P1-004", + "WBV2-P1-005" + ] + }, + { + "id": "P2", + "name": "core_modeler_loop", + "gate": "G2", + "tasks": [ + "WBV2-P2-001", + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P2-005" + ] + }, + { + "id": "P3", + "name": "authoring_and_io", + "gate": "G2", + "tasks": [ + "WBV2-P3-001", + "WBV2-P3-002", + "WBV2-P3-003", + "WBV2-P3-004", + "WBV2-P3-005" + ] + }, + { + "id": "P4", + "name": "advanced_local_slices", + "gate": "G2", + "tasks": [ + "WBV2-P4-001", + "WBV2-P4-002", + "WBV2-P4-003", + "WBV2-P4-004" + ] + }, + { + "id": "P5", + "name": "render_and_server", + "gate": "G3", + "tasks": [ + "WBV2-P5-001", + "WBV2-P5-002", + "WBV2-P5-003" + ] + }, + { + "id": "P6", + "name": "security_performance_release", + "gate": "G4", + "tasks": [ + "WBV2-P6-001", + "WBV2-P6-002", + "WBV2-P6-003" + ] + }, + { + "id": "P7", + "name": "full_parity_gap_program", + "gate": "G5", + "tasks": [ + "WBV2-P7-001", + "WBV2-P7-002", + "WBV2-P7-003" + ] + } + ], + "taskContract": { + "onePrimaryBehavior": true, + "requiredEvidence": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence", + "manifest", + "status" + ], + "requiredCommands": [ + "focused", + "determinism", + "hash", + "governance" + ], + "failureState": "in_progress_or_blocked", + "successorRule": "only_from_parent_manifest_nextTask" + }, + "tasks": [ + { + "id": "WBV2-P0-001", + "phase": "P0", + "title": "reconcile_scope_and_checkpoints", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-governance", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-001.md", + "behavior": "Freeze V1/full-parity boundary and reconcile legacy/corrective pointers without queue mutation.", + "outputs": [ + "scope decision", + "checkpoint report", + "protected hash set" + ], + "acceptance": [ + "corrective owner-review status is explicit", + "legacy parent pointer is unchanged", + "plan has one activation gate" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-002", + "phase": "P0", + "title": "generate_blender52_inventory_and_parity_map", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-inventory", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-002.md", + "behavior": "Generate stable Blender 5.2 data-block/operator/editor/node/format inventory and map every entry to a completion class.", + "outputs": [ + "inventory", + "parity map", + "source hash" + ], + "acceptance": [ + "unknown entries are classified", + "inventory is deterministic", + "no entry claims feature parity without evidence" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-003", + "phase": "P0", + "title": "freeze_capability_error_budget_contract", + "kind": "enabling", + "owner": "PROTOCOL", + "dependsOn": [ + "WBV2-P0-001", + "WBV2-P0-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-contract", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-003.md", + "behavior": "Freeze capability levels, stable error codes, revision, budget, cancellation and loss-report schemas.", + "outputs": [ + "versioned protocol", + "capability matrix", + "negative matrix" + ], + "acceptance": [ + "unsupported input fails closed", + "schema hashes are stable", + "migration policy preserves unknown data" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-001", + "phase": "P1", + "title": "stabilize_runtime_variants_and_source_receipts", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P0-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-runtime", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-001.md", + "behavior": "Bind single-thread/pthread WebEngine variants to pinned Blender source/build/runtime receipts.", + "outputs": [ + "runtime manifest", + "variant selector", + "fallback report" + ], + "acceptance": [ + "variant fallback is deterministic", + "source/build hash is verified", + "one engine session has one generation" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-002", + "phase": "P1", + "title": "unify_sceneir_stable_ids_and_binary_deltas", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-001" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-sceneir", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-002.md", + "behavior": "Make SceneIR/WBG1 stable IDs, topology/attribute domains and binary/range deltas canonical across desktop and WASM.", + "outputs": [ + "SceneIR schema", + "binary fixture", + "delta comparator" + ], + "acceptance": [ + "IDs survive save/reopen", + "malformed chunk is rejected", + "desktop and WASM canonical hashes match" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-003", + "phase": "P1", + "title": "unify_main_transaction_history_and_save", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-002" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-history", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-003.md", + "behavior": "Use one Main transaction/revision/history contract for commit, undo/redo, atomic save and reopen.", + "outputs": [ + "transaction contract", + "history receipt", + "save/reopen runner" + ], + "acceptance": [ + "failed/no-op commands add no history", + "stale revision cannot commit", + "reopen state is byte/hash stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-004", + "phase": "P1", + "title": "harden_worker_cancel_restart_and_dispose", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P1-001", + "WBV2-P1-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-lifecycle", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-004.md", + "behavior": "Make cancellation, late-result rejection, Worker restart and resource disposal common to all domains.", + "outputs": [ + "lifecycle runner", + "fault report", + "dispose counters" + ], + "acceptance": [ + "cancel never publishes result", + "generation mismatch is rejected", + "CPU/WASM/GPU owners return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-005", + "phase": "P1", + "title": "harden_opfs_indexeddb_journal_recovery", + "kind": "enabling", + "owner": "STORAGE", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P1-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-storage", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-005.md", + "behavior": "Unify OPFS staging/content addressing and IndexedDB metadata/journal recovery.", + "outputs": [ + "storage schema", + "crash fixtures", + "recovery checker" + ], + "acceptance": [ + "interrupted commit leaves old project usable", + "hash mismatch quarantines payload", + "small project recovers after restart" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-001", + "phase": "P2", + "title": "open_blend_scene_context_and_outliner", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P1-005" + ], + "parityId": "EDITOR.OPEN_SCENE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-editor", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-001.md", + "behavior": "Open a minimal .blend and expose scene/object/collection context from authoritative Main.", + "outputs": [ + "desktop fixture", + "outliner report", + "Chromium path" + ], + "acceptance": [ + "stable IDs and selection revision match", + "missing data is structured", + "reopen preserves context" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-002", + "phase": "P2", + "title": "object_collection_parent_transform_workflow", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P2-001" + ], + "parityId": "OBJECT.TRANSFORM_HIERARCHY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-scene", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-002.md", + "behavior": "Edit object transform, collection membership and parent hierarchy through Main transactions.", + "outputs": [ + "desktop/WASM golden", + "negative cases", + "save/reopen receipt" + ], + "acceptance": [ + "world matrix parity", + "cycle/locked/library edits reject", + "undo/redo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-003", + "phase": "P2", + "title": "mesh_edit_core_operations", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P2-002" + ], + "parityId": "MESH.EDIT_CORE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-mesh", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-003.md", + "behavior": "Expose bounded vertex/edge/face selection plus merge/dissolve/extrude/inset/bevel/loop-cut.", + "outputs": [ + "Blender fixture set", + "topology comparator", + "Chromium edit path" + ], + "acceptance": [ + "topology/attributes match", + "invalid selection and budget fail closed", + "single transaction and reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-004", + "phase": "P2", + "title": "dual_viewport_sceneir_render_path", + "kind": "feature", + "owner": "VIEWPORT", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P2-003" + ], + "parityId": "VIEWPORT.MAIN_OFFSCREEN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-viewport", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-004.md", + "behavior": "Render the same validated SceneIR through main-thread WebGL2 and OffscreenCanvas Worker paths.", + "outputs": [ + "pixel report", + "viewport diagnostics", + "device recovery" + ], + "acceptance": [ + "both paths have nonblank pixels", + "selection/camera revision is shared", + "device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-005", + "phase": "P2", + "title": "close_p0_user_loop", + "kind": "feature", + "owner": "INTEGRATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P1-005", + "WBV2-P2-004" + ], + "parityId": "WORKFLOW.P0_USER_LOOP", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-integration", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-005.md", + "behavior": "Prove open -> edit -> undo -> redo -> save -> restart -> reopen -> GLB in one production flow.", + "outputs": [ + "P0 workflow report", + "release binding", + "rollback receipt" + ], + "acceptance": [ + "Main revision and exported asset are bound", + "fault/cancel leaves old state", + "Chromium production path passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-001", + "phase": "P3", + "title": "material_uv_principled_asset_workflow", + "kind": "feature", + "owner": "MATERIAL", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005" + ], + "parityId": "MATERIAL.PBR_UV", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-001.md", + "behavior": "Edit material slots, UVs and declared Principled/Image/Normal graph nodes with content-addressed textures.", + "outputs": [ + "material golden", + "texture receipt", + "loss report" + ], + "acceptance": [ + "desktop/WASM node fields match", + "unsupported node retained/blocked", + "packed asset survives reopen" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-002", + "phase": "P3", + "title": "keyframe_timeline_action_workflow", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-005", + "WBV2-P3-001" + ], + "parityId": "ANIMATION.TRS_ACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-002.md", + "behavior": "Create/edit TRS keyframes, timeline and declared Action interpolation through Main.", + "outputs": [ + "frame golden", + "animation comparator", + "reopen report" + ], + "acceptance": [ + "sampled values and handles match", + "stale frame result rejected", + "undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-003", + "phase": "P3", + "title": "armature_pose_constraint_skin_workflow", + "kind": "feature", + "owner": "RIG", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P3-002" + ], + "parityId": "RIG.POSE_SKIN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-rig", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-003.md", + "behavior": "Read and edit declared armature pose/constraint/weight/shape-key slices with bounded evaluation.", + "outputs": [ + "pose golden", + "skin report", + "unsupported matrix" + ], + "acceptance": [ + "pose matrices and weights match", + "unsupported constraint is explicit", + "save/reopen and small recovery pass" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-004", + "phase": "P3", + "title": "glb_roundtrip_and_loss_report", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P2-005", + "WBV2-P3-001", + "WBV2-P3-003" + ], + "parityId": "IO.GLB_ROUNDTRIP", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-io", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-004.md", + "behavior": "Import/export declared GLB mesh/PBR/texture/morph/skin/animation and report non-mapped semantics.", + "outputs": [ + "GLB fixtures", + "desktop reimport report", + "loss report" + ], + "acceptance": [ + "roundtrip canonical graph matches", + "sparse/external URI/budget negatives reject", + "no silent loss" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-005", + "phase": "P3", + "title": "library_asset_append_link_override", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P2-001", + "WBV2-P3-004" + ], + "parityId": "ASSET.LIBRARY_OPERATIONS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-assets", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-005.md", + "behavior": "Support declared append/link/override ownership, reload and missing-library semantics.", + "outputs": [ + "library fixtures", + "ownership report", + "negative matrix" + ], + "acceptance": [ + "source/hash/owner identity preserved", + "linked mutation blocked", + "stale generation and missing source fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-001", + "phase": "P4", + "title": "modifier_graph_and_apply_slices", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005", + "WBV2-P3-005" + ], + "parityId": "MODIFIER.DECLARED_SLICES", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-001.md", + "behavior": "Enable one declared modifier parameter/apply workflow at a time with dependency-aware blocking.", + "outputs": [ + "modifier goldens", + "dependency report", + "negative cases" + ], + "acceptance": [ + "desktop/evaluated Main match", + "unknown modifier retained and blocked", + "apply/undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-002", + "phase": "P4", + "title": "geometry_nodes_and_shader_allowlist", + "kind": "feature", + "owner": "NODES", + "dependsOn": [ + "WBV2-P3-001", + "WBV2-P4-001" + ], + "parityId": "NODES.ALLOWLIST", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-002.md", + "behavior": "Read/write/evaluate only declared Geometry Nodes and shader graph allowlists with resource budgets.", + "outputs": [ + "node fixtures", + "compile/cache receipts", + "unsupported graph reports" + ], + "acceptance": [ + "node/socket/link/default parity", + "budget and unknown-node block before commit", + "compile failure rolls back" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-003", + "phase": "P4", + "title": "sculpt_nonmesh_and_paint_bounded_slices", + "kind": "feature", + "owner": "SCULPT", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P4-002" + ], + "parityId": "SCULPT.NONMESH.PAINT_BOUNDED", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-003.md", + "behavior": "Expose declared sculpt attributes/strokes, Curve/Surface/Font/PointCloud and paint slices with explicit PBVH limits.", + "outputs": [ + "non-mesh fixtures", + "stroke report", + "capability blocks" + ], + "acceptance": [ + "Main commit is atomic", + "unsupported brush/solver returns stable code", + "GPU/OOM/restart recovery passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-004", + "phase": "P4", + "title": "simulation_cache_identity_and_lifecycle", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P4-002", + "WBV2-P4-003" + ], + "parityId": "SIMULATION.CACHE_LIFECYCLE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G3", + "card": "docs/tasks/WBV2-P4-004.md", + "behavior": "Bind declared simulation cache to source/settings/revision hashes with cancellation, LRU and restart recovery.", + "outputs": [ + "cache fixtures", + "identity report", + "quarantine evidence" + ], + "acceptance": [ + "stale/corrupt cache never publishes", + "small cache recovers after restart", + "budget release is observable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-001", + "phase": "P5", + "title": "render_capability_routing", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P2-004", + "WBV2-P4-002", + "WBV2-P4-004" + ], + "parityId": "RENDER.ROUTING", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-001.md", + "behavior": "Route bounded Eevee/WebGL capabilities locally and unsupported render classes to SERVER_EXACT or EXCLUDED.", + "outputs": [ + "render receipts", + "pixel golden", + "routing report" + ], + "acceptance": [ + "source/settings/build identity bound", + "unsupported route cannot pretend local success", + "cancel/device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-002", + "phase": "P5", + "title": "compositor_sequencer_media_recovery", + "kind": "feature", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P3-002", + "WBV2-P5-001" + ], + "parityId": "MEDIA.BOUNDED_WORKFLOW", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-002.md", + "behavior": "Provide declared compositor/sequencer/codec/proxy/audio slices with revision and recovery gates.", + "outputs": [ + "media receipts", + "recovery report", + "audio/session diagnostics" + ], + "acceptance": [ + "seek/decode revision ordering", + "cancel/timeout does not publish", + "quota/OOM/restart leaves project valid" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-003", + "phase": "P5", + "title": "server_job_result_binding", + "kind": "feature", + "owner": "SERVER", + "dependsOn": [ + "WBV2-P0-003", + "WBV2-P5-001", + "WBV2-P5-002" + ], + "parityId": "SERVER.JOB_BINDING", + "implementationClass": "SERVER_EXACT", + "parallelGroup": "p5-server", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-003.md", + "behavior": "Bind server render/encode/physics jobs to immutable input/settings/build/output hashes and explicit lifecycle states.", + "outputs": [ + "server protocol", + "idempotency receipt", + "negative matrix" + ], + "acceptance": [ + "duplicate request is idempotent", + "stale result cannot bind", + "timeout/cancel/OOM produces no READY output" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-001", + "phase": "P6", + "title": "scripting_default_deny_and_audit", + "kind": "feature", + "owner": "SECURITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P5-003" + ], + "parityId": "SECURITY.SCRIPTING", + "implementationClass": "EXCLUDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-001.md", + "behavior": "Read text/metadata and expose audited, budgeted, default-deny script policy without arbitrary execution.", + "outputs": [ + "policy manifest", + "malicious fixtures", + "audit report" + ], + "acceptance": [ + "autorun/network/add-on defaults deny", + "sandbox cancellation/dispose works", + "no secret or filesystem escape" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-002", + "phase": "P6", + "title": "performance_fault_and_recovery_matrix", + "kind": "enabling", + "owner": "RELIABILITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P1-005", + "WBV2-P2-004", + "WBV2-P6-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-002.md", + "behavior": "Run deterministic geometry/texture/media/cache budgets and inject OOM/quota/device/network faults.", + "outputs": [ + "budget matrix", + "fault reports", + "resource release ledger" + ], + "acceptance": [ + "100k/1M/10M thresholds recorded", + "fault leaves old revision usable", + "all owned resources return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-003", + "phase": "P6", + "title": "offline_ci_sbom_and_rollback_release", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P6-001", + "WBV2-P6-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-release", + "gate": "G4", + "card": "docs/tasks/WBV2-P6-003.md", + "behavior": "Produce reproducible offline/source/binary release packages with CI lanes, SBOM and rollback evidence.", + "outputs": [ + "RC manifest", + "offline archive", + "CI reports" + ], + "acceptance": [ + "quick/Chromium/release lanes pass", + "artifact hashes reproduce", + "upgrade/rollback and known limitations are tested" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-001", + "phase": "P7", + "title": "cluster_full_blender_gap_inventory", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-002", + "WBV2-P6-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-001.md", + "behavior": "Cluster remaining Blender 5.2 data-block/operator/editor/node/format gaps by family and evidence class.", + "outputs": [ + "cluster catalog", + "coverage report", + "risk ranking" + ], + "acceptance": [ + "each gap has stable ID and owner", + "negative-only/unsupported is not positive parity", + "clusters are deterministic" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-002", + "phase": "P7", + "title": "generate_atomic_family_gap_queue", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-002.md", + "behavior": "Generate one task per parityId x observable behavior x implementation class with parent/hash context.", + "outputs": [ + "task index", + "task catalog", + "task cards" + ], + "acceptance": [ + "one active ready task", + "no guessed successor", + "each card fits context budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-003", + "phase": "P7", + "title": "full_parity_candidate_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P7-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P7-003.md", + "behavior": "Recompute parity closure, evidence health, recovery health and release decision from machine manifests.", + "outputs": [ + "parity release report", + "known limitations", + "final decision" + ], + "acceptance": [ + "all claims bind to evidence", + "blocked/excluded/server classes remain explicit", + "queue and protected hashes pass" + ], + "status": "blocked", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-000", + "phase": "P8", + "title": "authorize_recovery_capability_root", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-000.md", + "behavior": "Authorize a recovery epoch without rewriting the blocked P7 manifest.", + "outputs": [ + "recovery plan", + "root manifest", + "queue authorization" + ], + "acceptance": [ + "P7 evidence remains hash exact", + "recovery scope is explicit", + "one recovery task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P8-001", + "phase": "P8", + "title": "rebaseline_mutable_inventories", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-001.md", + "behavior": "Rebaseline mutable WBV2 plan and dependency inventory inputs while preserving historical manifests.", + "outputs": [ + "semantic drift report", + "current inventory baseline", + "manifest" + ], + "acceptance": [ + "only expected mutable hashes drift", + "dependency closure is unchanged", + "historical manifests remain unmodified" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-002", + "phase": "P8", + "title": "close_atomic_chromium_receipts", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P8-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-receipts", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-002.md", + "behavior": "Produce and bind all 45 atomic Chromium family receipts.", + "outputs": [ + "Chromium report", + "45 receipt index", + "receipt manifests" + ], + "acceptance": [ + "45 receipts are manifest-bound", + "desktop/WASM/save-reopen behaviors are explicit", + "Chromium is the only browser" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-003", + "phase": "P8", + "title": "authorize_m12_provenance_epoch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-provenance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-003.md", + "behavior": "Bind restored M12 sources and explicitly rebaseline unavailable originals in a new provenance epoch.", + "outputs": [ + "provenance epoch", + "replacement bindings", + "manifest" + ], + "acceptance": [ + "22 restored originals stay exact", + "62 unavailable entries are not called restored", + "all replacements are hash-bound" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-004", + "phase": "P8", + "title": "recompute_recovery_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P8-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-004.md", + "behavior": "Recompute the release decision from the recovery epoch and atomic receipts.", + "outputs": [ + "release gate", + "known limitations", + "final manifest" + ], + "acceptance": [ + "all receipts bind to manifests", + "provenance epoch is explicit", + "all governance gates pass" + ], + "status": "in_progress", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-000", + "phase": "P9", + "title": "authorize_feature_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-000.md", + "behavior": "Authorize feature parity continuation after provenance epoch 2 without claiming historical byte reproduction.", + "outputs": [ + "continuation receipt", + "feature parity plan", + "scope limits" + ], + "acceptance": [ + "P8 provenance evidence remains exact", + "authorized baseline is explicit", + "one feature task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P9-001", + "phase": "P9", + "title": "mesh_production_chromium_receipt", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P9-000" + ], + "parityId": "CAP-MESH-POSITIVE-EDIT", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-mesh", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-001.md", + "behavior": "Bind the existing Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt.", + "outputs": [ + "Chromium mesh receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real meshTranslateVertex command passes", + "desktop/WASM delta matches", + "save/reopen is exact", + "malformed/stale/unknown inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-002", + "phase": "P9", + "title": "modifier_production_chromium_receipt", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P9-001" + ], + "parityId": "CAP-MODIFIER-STATE-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-modifier", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-002.md", + "behavior": "Bind the existing Modifier Main transaction to a production Chromium receipt.", + "outputs": [ + "Chromium modifier receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real modifierSetEnabled command passes", + "desktop/WASM delta matches", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-003", + "phase": "P9", + "title": "asset_catalog_production_chromium_receipt", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P9-002" + ], + "parityId": "CAP-ASSET-CATALOG-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-asset", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-003.md", + "behavior": "Bind the existing Asset Catalog Main transaction and resource resolver to a production Chromium receipt.", + "outputs": [ + "Chromium asset receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real assetCatalogAppend command passes", + "resource hash is bound", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-004", + "phase": "P9", + "title": "recompute_feature_parity_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P9-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-release", + "gate": "G7", + "card": "docs/tasks/WBV2-P9-004.md", + "behavior": "Recompute declared feature parity claims from production Chromium receipts and authorized provenance.", + "outputs": [ + "feature parity gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only evidenced feature claims are emitted", + "authorized baseline remains explicit", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-000", + "phase": "P10", + "title": "authorize_native_engine_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P9-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-000.md", + "behavior": "Authorize native Blender/WASM engine parity continuation after bounded Chromium capability evidence.", + "outputs": [ + "continuation receipt", + "native parity plan", + "scope limits" + ], + "acceptance": [ + "P9 evidence remains hash-bound", + "native build/runtime is explicit", + "one native parity task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P10-001", + "phase": "P10", + "title": "reconcile_wbv2_inventory_source_drift", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-inventory", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-001.md", + "behavior": "Record the authorized mutable WBV2 plan drift and prove dependency closure stability without rewriting historical P0 evidence.", + "outputs": [ + "current source hash baseline", + "drift report", + "checker compatibility" + ], + "acceptance": [ + "historical P0 hashes remain unchanged", + "only authorized plan drift is recorded", + "dependency roots/lockfile/closure remain stable", + "inventory checker passes using current baseline" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-002", + "phase": "P10", + "title": "bind_native_and_wasm_engine_receipts", + "kind": "feature", + "owner": "ENGINE", + "dependsOn": [ + "WBV2-P10-001" + ], + "parityId": "ENGINE.NATIVE_WASM_BRIDGE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p10-engine", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-002.md", + "behavior": "Bind Mesh, Modifier, and Asset Catalog receipts to the compiled Blender native binary and web_engine.wasm runtime.", + "outputs": [ + "native receipt", + "WASM receipt", + "Chromium engine report" + ], + "acceptance": [ + "native Blender binary is source-bound", + "WASM binary and JS are hash-bound", + "same mutation reaches real engine/Main", + "save/reopen and failures remain exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-003", + "phase": "P10", + "title": "expand_core_module_operator_matrix", + "kind": "feature", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-002" + ], + "parityId": "CORE.MODULE_MATRIX", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-matrix", + "gate": "G7", + "card": "docs/tasks/WBV2-P10-003.md", + "behavior": "Expand the three proven capability modules with data-driven operator coverage and aggregate regression receipts.", + "outputs": [ + "module matrix", + "shard reports", + "aggregate manifest" + ], + "acceptance": [ + "positive cases are L2+", + "negative cases do not mutate Main", + "shards use one catalog hash", + "unmapped and retained-negative cases stay explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-000", + "phase": "P11", + "title": "authorize_module_expansion_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P10-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-governance", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-000.md", + "behavior": "Authorize deeper module production after real native/WASM engine binding and the first aggregate matrix.", + "outputs": [ + "continuation root", + "module expansion plan", + "scope limits" + ], + "acceptance": [ + "P10 evidence remains hash-bound", + "one expansion task is active", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P11-001", + "phase": "P11", + "title": "mesh_topology_operation_family", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P11-000" + ], + "parityId": "MESH.EDIT_TOPOLOGY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-mesh", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-001.md", + "behavior": "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real Blender WASM Main and preserve each result through save/reopen.", + "outputs": [ + "topology receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "six mesh operations mutate Main", + "revision increments exactly once", + "save/reopen preserves topology counts", + "invalid selection and incompatible configuration fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-002", + "phase": "P11", + "title": "modifier_parameter_apply_family", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P11-001" + ], + "parityId": "MODIFIER.PARAMETER_APPLY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-modifier", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-002.md", + "behavior": "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", + "outputs": [ + "modifier parameter receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "parameter mutation is native/WASM bound", + "apply result is evaluated", + "save/reopen is exact", + "dependency and stale inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-003", + "phase": "P11", + "title": "asset_link_override_reload_family", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P11-002" + ], + "parityId": "ASSET.LINK_OVERRIDE_RELOAD_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-asset", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-003.md", + "behavior": "Extend the real Asset Main path from append to link, override, reload, and missing-library boundaries.", + "outputs": [ + "asset ownership receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "source ownership is preserved", + "override is local and hash-bound", + "reload revision is checked", + "missing source remains explicit" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-004", + "phase": "P11", + "title": "recompute_engine_module_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P11-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-release", + "gate": "G8", + "card": "docs/tasks/WBV2-P11-004.md", + "behavior": "Recompute engine-bound module parity from P10 and P11 receipts without claiming whole-inventory completion.", + "outputs": [ + "engine module gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only engine-bound claims are emitted", + "inventory remainder is explicit", + "provenance epoch 2 remains authorized rebaseline only", + "full historical reproduction remains false" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ], + "parentPlan": { + "path": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "sha256": "0f4750e45f2d1ca7d68faa35743e5b758ea8091f18d1d0e312ab548228d6f782" + }, + "recoveryRoot": "WBV2-P11-000", + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P11-001/module-expansion-task-plan.json", + "sha256": "909447163efc1ea0b015a68e838ae9e87e9a8867be008ae16e34349c2dcad650" + } +} diff --git a/tests/golden/WBV2-P11-002/task-context.json b/tests/golden/WBV2-P11-002/task-context.json new file mode 100644 index 000000000..8bbf90771 --- /dev/null +++ b/tests/golden/WBV2-P11-002/task-context.json @@ -0,0 +1,170 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-002", + "parentTask": "WBV2-P11-001", + "status": "in_progress", + "goal": "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", + "scope": { + "gap": "workflow:modifier_parameter_apply_family", + "ownerFamily": "MODIFIER", + "implementationClass": "LOCAL_EXACT" + }, + "commands": [ + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-parameter-production.spec.ts", + "node tools/web/generate-wbv2-modifier-parameter-receipt.mjs --write", + "node tools/web/check-task-context.mjs --task WBV2-P11-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2265, + "contextRemainingTokens": 565 + }, + "source": { + "bytes": 7639, + "tokens": 1911 + }, + "selected": [], + "excluded": [ + { + "path": "tests/files/web/generated/WBV2-P4-001-MODIFIER.DECLARED_SLICES.blend", + "bytes": 87318, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "bytes": 3733, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", + "bytes": 243862, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P11-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P11-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "parameter mutation is native/WASM bound", + "apply result is evaluated", + "save/reopen is exact", + "dependency and stale inputs fail closed" + ], + "nextTask": "WBV2-P11-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P11-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P11-001/manifest.json", + "parentStatus": "docs/status/WBV2-P11-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P11-002.md", + "tests/golden/WBV2-P11-001/manifest.json", + "docs/status/WBV2-P11-001.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-P11-001", + "parentTask": "WBV2-P11-000", + "status": "done", + "nextTask": "WBV2-P11-002", + "artifactCount": 13 + }, + "statusSummary": [ + "# WBV2-P11-001 status", + "- task: `WBV2-P11-001`; parent: `WBV2-P11-000`; status: `done`", + "- topology operations: `MERGE, DISSOLVE, EXTRUDE, INSET, BEVEL, LOOP_CUT`", + "- real WASM Main mutations: `6/6`; revision delta: `+1 each`; save/reopen: `6/6 EXACT`", + "- negative cases: invalid selection, incompatible configuration, stale revision; Main unchanged", + "- nextTask: `WBV2-P11-002`", + "The six bounded Mesh topology operations execute through the compiled WebEngine WASM Main and preserve topology summaries through save/reopen. Invalid selection, incompatible operation configuration, and stale revision fail closed. This is an engine-bound capability slice, not a claim that the complete Blender operator inventory is finished or that historical bytes were reproduced." + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1257, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 33, + "taskTokens": 315 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P11-002.md", + "bytes": 1257, + "lines": 33, + "tokens": 315 + }, + { + "path": "tests/golden/WBV2-P11-001/manifest.json", + "bytes": 2823, + "lines": 75, + "tokens": 706 + }, + { + "path": "docs/status/WBV2-P11-001.md", + "bytes": 756, + "lines": 10, + "tokens": 189 + } + ], + "sourceTokens": 1911, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1911, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2935, + "serializedContextTokens": 664, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P11-003/asset-link-override-production.json b/tests/golden/WBV2-P11-003/asset-link-override-production.json new file mode 100644 index 000000000..663de959d --- /dev/null +++ b/tests/golden/WBV2-P11-003/asset-link-override-production.json @@ -0,0 +1,121 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-003", + "operation": "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_CHROMIUM", + "browser": "chromium", + "queueMutation": false, + "linked": { + "before": { + "id": null, + "visible": null, + "objectPresent": false, + "libraries": [ + { + "dependencyIds": [], + "errorCode": "LINKED_LIBRARY_RESOURCE_REQUIRED", + "id": "library:WBV2P3005Library.blend", + "name": "WBV2P3005Library.blend", + "packed": false, + "readOnly": true, + "sourcePath": "//WBV2P3005Library.blend", + "status": "EXTERNAL_REQUIRED" + } + ], + "libraryStatus": "AVAILABLE" + }, + "mutation": { + "code": "LINKED_LIBRARY_REQUIRED", + "message": "linked object withheld while external library is unavailable" + }, + "after": { + "id": null, + "visible": null, + "objectPresent": false + }, + "revisionBefore": 1, + "revisionAfter": 1 + }, + "append": { + "baseRevision": 1, + "appendedRevision": 2, + "receipt": { + "schemaVersion": 1, + "operation": "APPEND", + "sourceLibraryId": "library:2e0d46a97a5c7e34b76ba16a594ce76a12553ddd795992c3f48d6c1d32826153", + "sourceDataBlockId": "Object/WBV2P3005AppendObject", + "dependencyClosureSha256": "f065b78b4bb80189c2258f78725c3254d6853ecf7f4a34d4b91c62ec28a6670d", + "baseRevision": 1, + "nextRevision": 2, + "transactionCount": 1, + "mapping": [ + { + "source": "Object/WBV2P3005AppendObject", + "local": "Object/WBV2P3005AppendObject", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Mesh/WBV2P3005AppendMesh", + "local": "Mesh/WBV2P3005AppendMesh", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Material/WBV2P3005AppendMaterial", + "local": "Material/WBV2P3005AppendMaterial", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Image/WBV2P3005AppendImage", + "local": "Image/WBV2P3005AppendImage", + "owner": "LOCAL_MAIN", + "readOnly": false + } + ] + }, + "local": { + "object": { + "id": "object:WBV2P3005AppendObject", + "type": "MESH", + "dataId": "mesh:WBV2P3005AppendMesh" + }, + "mesh": { + "id": "mesh:WBV2P3005AppendMesh", + "materialSlotIds": [ + "material:WBV2P3005AppendMaterial" + ], + "vertexCount": 4 + }, + "material": { + "id": "material:WBV2P3005AppendMaterial", + "imageIds": [ + "image:WBV2P3005AppendImage" + ] + }, + "image": { + "id": "image:WBV2P3005AppendImage", + "libraryLinked": false, + "packed": true, + "assetStatus": "PACKED" + } + }, + "reopened": { + "object": true, + "mesh": true, + "material": true, + "image": { + "libraryLinked": false, + "packed": true + } + }, + "saveReopenExact": true, + "savedSha256": "8de2d2c32d57d8520b8881d2a1eb133673946b30f394843227c3d2d6d984b043", + "sourceSha256": "dcda742db77c6af5e05b79e006a0bd89cf1e8ea8d438592cd1ed2e981c7aca76", + "stale": { + "code": "REVISION_CONFLICT", + "message": "REVISION_CONFLICT: library append base revision is stale" + }, + "revisionAfterStale": 2 + } +} diff --git a/tests/golden/WBV2-P11-003/asset-link-override-production.second.json b/tests/golden/WBV2-P11-003/asset-link-override-production.second.json new file mode 100644 index 000000000..663de959d --- /dev/null +++ b/tests/golden/WBV2-P11-003/asset-link-override-production.second.json @@ -0,0 +1,121 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-003", + "operation": "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_CHROMIUM", + "browser": "chromium", + "queueMutation": false, + "linked": { + "before": { + "id": null, + "visible": null, + "objectPresent": false, + "libraries": [ + { + "dependencyIds": [], + "errorCode": "LINKED_LIBRARY_RESOURCE_REQUIRED", + "id": "library:WBV2P3005Library.blend", + "name": "WBV2P3005Library.blend", + "packed": false, + "readOnly": true, + "sourcePath": "//WBV2P3005Library.blend", + "status": "EXTERNAL_REQUIRED" + } + ], + "libraryStatus": "AVAILABLE" + }, + "mutation": { + "code": "LINKED_LIBRARY_REQUIRED", + "message": "linked object withheld while external library is unavailable" + }, + "after": { + "id": null, + "visible": null, + "objectPresent": false + }, + "revisionBefore": 1, + "revisionAfter": 1 + }, + "append": { + "baseRevision": 1, + "appendedRevision": 2, + "receipt": { + "schemaVersion": 1, + "operation": "APPEND", + "sourceLibraryId": "library:2e0d46a97a5c7e34b76ba16a594ce76a12553ddd795992c3f48d6c1d32826153", + "sourceDataBlockId": "Object/WBV2P3005AppendObject", + "dependencyClosureSha256": "f065b78b4bb80189c2258f78725c3254d6853ecf7f4a34d4b91c62ec28a6670d", + "baseRevision": 1, + "nextRevision": 2, + "transactionCount": 1, + "mapping": [ + { + "source": "Object/WBV2P3005AppendObject", + "local": "Object/WBV2P3005AppendObject", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Mesh/WBV2P3005AppendMesh", + "local": "Mesh/WBV2P3005AppendMesh", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Material/WBV2P3005AppendMaterial", + "local": "Material/WBV2P3005AppendMaterial", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Image/WBV2P3005AppendImage", + "local": "Image/WBV2P3005AppendImage", + "owner": "LOCAL_MAIN", + "readOnly": false + } + ] + }, + "local": { + "object": { + "id": "object:WBV2P3005AppendObject", + "type": "MESH", + "dataId": "mesh:WBV2P3005AppendMesh" + }, + "mesh": { + "id": "mesh:WBV2P3005AppendMesh", + "materialSlotIds": [ + "material:WBV2P3005AppendMaterial" + ], + "vertexCount": 4 + }, + "material": { + "id": "material:WBV2P3005AppendMaterial", + "imageIds": [ + "image:WBV2P3005AppendImage" + ] + }, + "image": { + "id": "image:WBV2P3005AppendImage", + "libraryLinked": false, + "packed": true, + "assetStatus": "PACKED" + } + }, + "reopened": { + "object": true, + "mesh": true, + "material": true, + "image": { + "libraryLinked": false, + "packed": true + } + }, + "saveReopenExact": true, + "savedSha256": "8de2d2c32d57d8520b8881d2a1eb133673946b30f394843227c3d2d6d984b043", + "sourceSha256": "dcda742db77c6af5e05b79e006a0bd89cf1e8ea8d438592cd1ed2e981c7aca76", + "stale": { + "code": "REVISION_CONFLICT", + "message": "REVISION_CONFLICT: library append base revision is stale" + }, + "revisionAfterStale": 2 + } +} diff --git a/tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json b/tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json new file mode 100644 index 000000000..e399290b7 --- /dev/null +++ b/tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json @@ -0,0 +1,90 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-003", + "operation": "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_RECEIPT", + "status": "PASS", + "browser": "chromium", + "queueMutation": false, + "source": { + "task": "WBV2-P3-005", + "manifest": "tests/golden/WBV2-P3-005/manifest.json", + "manifestSha256": "42dc02d198630c2735c5a0a1beab37f2a98ff0233927215099f67606d248c39e", + "report": "tests/golden/WBV2-P3-005/library-report.json", + "reportSha256": "0b572a5b480dd9b123cbb9c55c842fb002b1a8a6c96afd196af90bee1ebd9940", + "linkOverrideReloadEvidence": true, + "sourceSaveReopenExact": true + }, + "engine": { + "receipt": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "receiptSha256": "09c13b1814d61a6132ae1168d999e09b768915fe7fec652b6b965f9a6d3796f9", + "compiledWasmBound": true, + "realEngineMainMutation": true + }, + "production": { + "report": "tests/golden/WBV2-P11-003/asset-link-override-production.json", + "reportSha256": "1930629c375c9b71bf7a3ad8213c29348cc8ca078f38562341825e038d065afe", + "secondReport": "tests/golden/WBV2-P11-003/asset-link-override-production.second.json", + "secondReportSha256": "1930629c375c9b71bf7a3ad8213c29348cc8ca078f38562341825e038d065afe", + "deterministic": true, + "linkedMissingSource": { + "libraryStatus": "AVAILABLE", + "resourceStatus": "EXTERNAL_REQUIRED", + "readOnly": true, + "objectWithheld": true, + "mutationRejected": true + }, + "localAppend": { + "receipt": { + "schemaVersion": 1, + "operation": "APPEND", + "sourceLibraryId": "library:2e0d46a97a5c7e34b76ba16a594ce76a12553ddd795992c3f48d6c1d32826153", + "sourceDataBlockId": "Object/WBV2P3005AppendObject", + "dependencyClosureSha256": "f065b78b4bb80189c2258f78725c3254d6853ecf7f4a34d4b91c62ec28a6670d", + "baseRevision": 1, + "nextRevision": 2, + "transactionCount": 1, + "mapping": [ + { + "source": "Object/WBV2P3005AppendObject", + "local": "Object/WBV2P3005AppendObject", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Mesh/WBV2P3005AppendMesh", + "local": "Mesh/WBV2P3005AppendMesh", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Material/WBV2P3005AppendMaterial", + "local": "Material/WBV2P3005AppendMaterial", + "owner": "LOCAL_MAIN", + "readOnly": false + }, + { + "source": "Image/WBV2P3005AppendImage", + "local": "Image/WBV2P3005AppendImage", + "owner": "LOCAL_MAIN", + "readOnly": false + } + ] + }, + "revisionDelta": 1, + "localOwnership": true, + "saveReopen": true, + "staleRejected": true + } + }, + "assertions": { + "sourceOwnershipPreserved": true, + "localOverrideReuseBound": true, + "missingResourceExplicit": true, + "linkedMutationRejected": true, + "localAppendMainChanged": true, + "saveReopenExact": true, + "staleRevisionRejected": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P11-004" +} diff --git a/tests/golden/WBV2-P11-003/manifest.json b/tests/golden/WBV2-P11-003/manifest.json new file mode 100644 index 000000000..dd2b9bfb7 --- /dev/null +++ b/tests/golden/WBV2-P11-003/manifest.json @@ -0,0 +1,78 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-003", + "parentTask": "WBV2-P11-002", + "operation": "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_RECEIPT", + "status": "done", + "enablingTask": false, + "parityStateChange": true, + "runtime": "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P11-002/manifest.json", + "sha256": "32b9581bc0ef2cd3435a17c3b7d454ae5327ef8f0ac4c1916e9a0857eb42aaf1" + }, + "sourceManifest": { + "path": "tests/golden/WBV2-P3-005/manifest.json", + "sha256": "42dc02d198630c2735c5a0a1beab37f2a98ff0233927215099f67606d248c39e" + }, + "sourceReport": { + "path": "tests/golden/WBV2-P3-005/library-report.json", + "sha256": "0b572a5b480dd9b123cbb9c55c842fb002b1a8a6c96afd196af90bee1ebd9940" + }, + "engineReceipt": { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "sha256": "09c13b1814d61a6132ae1168d999e09b768915fe7fec652b6b965f9a6d3796f9" + }, + "production": { + "path": "tests/golden/WBV2-P11-003/asset-link-override-production.json", + "sha256": "1930629c375c9b71bf7a3ad8213c29348cc8ca078f38562341825e038d065afe" + }, + "productionSecond": { + "path": "tests/golden/WBV2-P11-003/asset-link-override-production.second.json", + "sha256": "1930629c375c9b71bf7a3ad8213c29348cc8ca078f38562341825e038d065afe" + }, + "e2e": { + "path": "web/tests/e2e/wbv2-asset-link-override-production.spec.ts", + "sha256": "96978326d189dcd062b3029b8141a0cb2550fe0cebf7cfc3d63733b043467a83" + }, + "protocol": { + "path": "web/app/src/engine-client/WebEngineClient.ts", + "sha256": "f6d9a8e0a16403bc6fb765195b8f1a619a28de7a75c59a412f1654d46e8ebc0b" + }, + "nativeApi": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8" + }, + "generator": { + "path": "tools/web/generate-wbv2-asset-link-override-receipt.mjs", + "sha256": "9d574b96e59aaaac8846ec318ab5acfd77d1c8fc74662d3f72107adaf88a767b" + }, + "report": { + "path": "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json", + "sha256": "d7eb0e3a0017fdb1780ba124c540e4967a01b7ea45303146b9ebc86327db48b9" + }, + "status": { + "path": "docs/status/WBV2-P11-003.md", + "sha256": "63aefc995b227dc95cb5650349d9a1c462202328eb36438e2bef3cdf119903fd" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P11-003/module-expansion-task-plan.json", + "sha256": "d4c7be339c4b0455d82b4f4c4baab6a4f47909883b9da3c1de9e61ea8001b898" + }, + "taskContext": { + "path": "tests/golden/WBV2-P11-003/task-context.json", + "sha256": "62b0acbaffa88b32bca0f04e6db0adfea8dc2a68e5d7f1aa9a3cd1518ad9a323" + } + }, + "assertions": { + "linkedMissingSourceExplicit": true, + "localOwnership": true, + "appendRevisionDelta": 1, + "saveReopen": "EXACT", + "staleRejected": true, + "deterministic": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P11-004" +} diff --git a/tests/golden/WBV2-P11-003/module-expansion-task-plan.json b/tests/golden/WBV2-P11-003/module-expansion-task-plan.json new file mode 100644 index 000000000..1906b59f8 --- /dev/null +++ b/tests/golden/WBV2-P11-003/module-expansion-task-plan.json @@ -0,0 +1,1716 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_MODULE_EXPANSION_EPOCH_1", + "status": "ACTIVE_MODULE_EXPANSION_QUEUE", + "authority": "queue_reactivated_after_p10_engine_matrix", + "productContract": "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "sourcePlan": "docs/BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "correctiveCheckpoint": { + "task": "C6-003", + "handoff": "tests/golden/corrective/C6-003/handoff.json", + "status": "active", + "blocker": null, + "queueMutation": true, + "legacyTask": "M16-GAP-00277", + "legacyParentNextTask": "M16-GAP-00277" + }, + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "storage": [ + "opfs", + "indexeddb" + ], + "queueMutation": "enabled_after_owner_review_and_g5" + }, + "completionClasses": [ + "LOCAL_EXACT", + "LOCAL_BOUNDED", + "SERVER_EXACT", + "EXCLUDED" + ], + "gates": [ + { + "id": "G0", + "name": "scope_and_inventory", + "requires": [ + "contract", + "inventory", + "capability_matrix" + ] + }, + { + "id": "G1", + "name": "runtime_foundation", + "requires": [ + "sceneir", + "main_transaction", + "worker_lifecycle", + "storage_journal" + ] + }, + { + "id": "G2", + "name": "feature_parity", + "requires": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence" + ] + }, + { + "id": "G3", + "name": "recovery_and_security", + "requires": [ + "cancel", + "restart", + "oom_quota", + "malformed", + "dispose" + ] + }, + { + "id": "G4", + "name": "release_candidate", + "requires": [ + "offline", + "ci", + "sbom", + "rollback", + "hashes" + ] + }, + { + "id": "G5", + "name": "queue_mutation", + "requires": [ + "owner_review", + "protected_hashes", + "handoff", + "single_ready_task" + ] + } + ], + "waves": [ + { + "id": "P0", + "name": "facts_and_contracts", + "gate": "G0", + "tasks": [ + "WBV2-P0-001", + "WBV2-P0-002", + "WBV2-P0-003" + ] + }, + { + "id": "P1", + "name": "runtime_foundation", + "gate": "G1", + "tasks": [ + "WBV2-P1-001", + "WBV2-P1-002", + "WBV2-P1-003", + "WBV2-P1-004", + "WBV2-P1-005" + ] + }, + { + "id": "P2", + "name": "core_modeler_loop", + "gate": "G2", + "tasks": [ + "WBV2-P2-001", + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P2-005" + ] + }, + { + "id": "P3", + "name": "authoring_and_io", + "gate": "G2", + "tasks": [ + "WBV2-P3-001", + "WBV2-P3-002", + "WBV2-P3-003", + "WBV2-P3-004", + "WBV2-P3-005" + ] + }, + { + "id": "P4", + "name": "advanced_local_slices", + "gate": "G2", + "tasks": [ + "WBV2-P4-001", + "WBV2-P4-002", + "WBV2-P4-003", + "WBV2-P4-004" + ] + }, + { + "id": "P5", + "name": "render_and_server", + "gate": "G3", + "tasks": [ + "WBV2-P5-001", + "WBV2-P5-002", + "WBV2-P5-003" + ] + }, + { + "id": "P6", + "name": "security_performance_release", + "gate": "G4", + "tasks": [ + "WBV2-P6-001", + "WBV2-P6-002", + "WBV2-P6-003" + ] + }, + { + "id": "P7", + "name": "full_parity_gap_program", + "gate": "G5", + "tasks": [ + "WBV2-P7-001", + "WBV2-P7-002", + "WBV2-P7-003" + ] + } + ], + "taskContract": { + "onePrimaryBehavior": true, + "requiredEvidence": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence", + "manifest", + "status" + ], + "requiredCommands": [ + "focused", + "determinism", + "hash", + "governance" + ], + "failureState": "in_progress_or_blocked", + "successorRule": "only_from_parent_manifest_nextTask" + }, + "tasks": [ + { + "id": "WBV2-P0-001", + "phase": "P0", + "title": "reconcile_scope_and_checkpoints", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-governance", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-001.md", + "behavior": "Freeze V1/full-parity boundary and reconcile legacy/corrective pointers without queue mutation.", + "outputs": [ + "scope decision", + "checkpoint report", + "protected hash set" + ], + "acceptance": [ + "corrective owner-review status is explicit", + "legacy parent pointer is unchanged", + "plan has one activation gate" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-002", + "phase": "P0", + "title": "generate_blender52_inventory_and_parity_map", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-inventory", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-002.md", + "behavior": "Generate stable Blender 5.2 data-block/operator/editor/node/format inventory and map every entry to a completion class.", + "outputs": [ + "inventory", + "parity map", + "source hash" + ], + "acceptance": [ + "unknown entries are classified", + "inventory is deterministic", + "no entry claims feature parity without evidence" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-003", + "phase": "P0", + "title": "freeze_capability_error_budget_contract", + "kind": "enabling", + "owner": "PROTOCOL", + "dependsOn": [ + "WBV2-P0-001", + "WBV2-P0-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-contract", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-003.md", + "behavior": "Freeze capability levels, stable error codes, revision, budget, cancellation and loss-report schemas.", + "outputs": [ + "versioned protocol", + "capability matrix", + "negative matrix" + ], + "acceptance": [ + "unsupported input fails closed", + "schema hashes are stable", + "migration policy preserves unknown data" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-001", + "phase": "P1", + "title": "stabilize_runtime_variants_and_source_receipts", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P0-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-runtime", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-001.md", + "behavior": "Bind single-thread/pthread WebEngine variants to pinned Blender source/build/runtime receipts.", + "outputs": [ + "runtime manifest", + "variant selector", + "fallback report" + ], + "acceptance": [ + "variant fallback is deterministic", + "source/build hash is verified", + "one engine session has one generation" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-002", + "phase": "P1", + "title": "unify_sceneir_stable_ids_and_binary_deltas", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-001" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-sceneir", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-002.md", + "behavior": "Make SceneIR/WBG1 stable IDs, topology/attribute domains and binary/range deltas canonical across desktop and WASM.", + "outputs": [ + "SceneIR schema", + "binary fixture", + "delta comparator" + ], + "acceptance": [ + "IDs survive save/reopen", + "malformed chunk is rejected", + "desktop and WASM canonical hashes match" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-003", + "phase": "P1", + "title": "unify_main_transaction_history_and_save", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-002" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-history", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-003.md", + "behavior": "Use one Main transaction/revision/history contract for commit, undo/redo, atomic save and reopen.", + "outputs": [ + "transaction contract", + "history receipt", + "save/reopen runner" + ], + "acceptance": [ + "failed/no-op commands add no history", + "stale revision cannot commit", + "reopen state is byte/hash stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-004", + "phase": "P1", + "title": "harden_worker_cancel_restart_and_dispose", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P1-001", + "WBV2-P1-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-lifecycle", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-004.md", + "behavior": "Make cancellation, late-result rejection, Worker restart and resource disposal common to all domains.", + "outputs": [ + "lifecycle runner", + "fault report", + "dispose counters" + ], + "acceptance": [ + "cancel never publishes result", + "generation mismatch is rejected", + "CPU/WASM/GPU owners return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-005", + "phase": "P1", + "title": "harden_opfs_indexeddb_journal_recovery", + "kind": "enabling", + "owner": "STORAGE", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P1-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-storage", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-005.md", + "behavior": "Unify OPFS staging/content addressing and IndexedDB metadata/journal recovery.", + "outputs": [ + "storage schema", + "crash fixtures", + "recovery checker" + ], + "acceptance": [ + "interrupted commit leaves old project usable", + "hash mismatch quarantines payload", + "small project recovers after restart" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-001", + "phase": "P2", + "title": "open_blend_scene_context_and_outliner", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P1-005" + ], + "parityId": "EDITOR.OPEN_SCENE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-editor", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-001.md", + "behavior": "Open a minimal .blend and expose scene/object/collection context from authoritative Main.", + "outputs": [ + "desktop fixture", + "outliner report", + "Chromium path" + ], + "acceptance": [ + "stable IDs and selection revision match", + "missing data is structured", + "reopen preserves context" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-002", + "phase": "P2", + "title": "object_collection_parent_transform_workflow", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P2-001" + ], + "parityId": "OBJECT.TRANSFORM_HIERARCHY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-scene", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-002.md", + "behavior": "Edit object transform, collection membership and parent hierarchy through Main transactions.", + "outputs": [ + "desktop/WASM golden", + "negative cases", + "save/reopen receipt" + ], + "acceptance": [ + "world matrix parity", + "cycle/locked/library edits reject", + "undo/redo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-003", + "phase": "P2", + "title": "mesh_edit_core_operations", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P2-002" + ], + "parityId": "MESH.EDIT_CORE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-mesh", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-003.md", + "behavior": "Expose bounded vertex/edge/face selection plus merge/dissolve/extrude/inset/bevel/loop-cut.", + "outputs": [ + "Blender fixture set", + "topology comparator", + "Chromium edit path" + ], + "acceptance": [ + "topology/attributes match", + "invalid selection and budget fail closed", + "single transaction and reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-004", + "phase": "P2", + "title": "dual_viewport_sceneir_render_path", + "kind": "feature", + "owner": "VIEWPORT", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P2-003" + ], + "parityId": "VIEWPORT.MAIN_OFFSCREEN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-viewport", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-004.md", + "behavior": "Render the same validated SceneIR through main-thread WebGL2 and OffscreenCanvas Worker paths.", + "outputs": [ + "pixel report", + "viewport diagnostics", + "device recovery" + ], + "acceptance": [ + "both paths have nonblank pixels", + "selection/camera revision is shared", + "device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-005", + "phase": "P2", + "title": "close_p0_user_loop", + "kind": "feature", + "owner": "INTEGRATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P1-005", + "WBV2-P2-004" + ], + "parityId": "WORKFLOW.P0_USER_LOOP", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-integration", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-005.md", + "behavior": "Prove open -> edit -> undo -> redo -> save -> restart -> reopen -> GLB in one production flow.", + "outputs": [ + "P0 workflow report", + "release binding", + "rollback receipt" + ], + "acceptance": [ + "Main revision and exported asset are bound", + "fault/cancel leaves old state", + "Chromium production path passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-001", + "phase": "P3", + "title": "material_uv_principled_asset_workflow", + "kind": "feature", + "owner": "MATERIAL", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005" + ], + "parityId": "MATERIAL.PBR_UV", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-001.md", + "behavior": "Edit material slots, UVs and declared Principled/Image/Normal graph nodes with content-addressed textures.", + "outputs": [ + "material golden", + "texture receipt", + "loss report" + ], + "acceptance": [ + "desktop/WASM node fields match", + "unsupported node retained/blocked", + "packed asset survives reopen" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-002", + "phase": "P3", + "title": "keyframe_timeline_action_workflow", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-005", + "WBV2-P3-001" + ], + "parityId": "ANIMATION.TRS_ACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-002.md", + "behavior": "Create/edit TRS keyframes, timeline and declared Action interpolation through Main.", + "outputs": [ + "frame golden", + "animation comparator", + "reopen report" + ], + "acceptance": [ + "sampled values and handles match", + "stale frame result rejected", + "undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-003", + "phase": "P3", + "title": "armature_pose_constraint_skin_workflow", + "kind": "feature", + "owner": "RIG", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P3-002" + ], + "parityId": "RIG.POSE_SKIN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-rig", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-003.md", + "behavior": "Read and edit declared armature pose/constraint/weight/shape-key slices with bounded evaluation.", + "outputs": [ + "pose golden", + "skin report", + "unsupported matrix" + ], + "acceptance": [ + "pose matrices and weights match", + "unsupported constraint is explicit", + "save/reopen and small recovery pass" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-004", + "phase": "P3", + "title": "glb_roundtrip_and_loss_report", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P2-005", + "WBV2-P3-001", + "WBV2-P3-003" + ], + "parityId": "IO.GLB_ROUNDTRIP", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-io", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-004.md", + "behavior": "Import/export declared GLB mesh/PBR/texture/morph/skin/animation and report non-mapped semantics.", + "outputs": [ + "GLB fixtures", + "desktop reimport report", + "loss report" + ], + "acceptance": [ + "roundtrip canonical graph matches", + "sparse/external URI/budget negatives reject", + "no silent loss" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-005", + "phase": "P3", + "title": "library_asset_append_link_override", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P2-001", + "WBV2-P3-004" + ], + "parityId": "ASSET.LIBRARY_OPERATIONS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-assets", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-005.md", + "behavior": "Support declared append/link/override ownership, reload and missing-library semantics.", + "outputs": [ + "library fixtures", + "ownership report", + "negative matrix" + ], + "acceptance": [ + "source/hash/owner identity preserved", + "linked mutation blocked", + "stale generation and missing source fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-001", + "phase": "P4", + "title": "modifier_graph_and_apply_slices", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005", + "WBV2-P3-005" + ], + "parityId": "MODIFIER.DECLARED_SLICES", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-001.md", + "behavior": "Enable one declared modifier parameter/apply workflow at a time with dependency-aware blocking.", + "outputs": [ + "modifier goldens", + "dependency report", + "negative cases" + ], + "acceptance": [ + "desktop/evaluated Main match", + "unknown modifier retained and blocked", + "apply/undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-002", + "phase": "P4", + "title": "geometry_nodes_and_shader_allowlist", + "kind": "feature", + "owner": "NODES", + "dependsOn": [ + "WBV2-P3-001", + "WBV2-P4-001" + ], + "parityId": "NODES.ALLOWLIST", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-002.md", + "behavior": "Read/write/evaluate only declared Geometry Nodes and shader graph allowlists with resource budgets.", + "outputs": [ + "node fixtures", + "compile/cache receipts", + "unsupported graph reports" + ], + "acceptance": [ + "node/socket/link/default parity", + "budget and unknown-node block before commit", + "compile failure rolls back" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-003", + "phase": "P4", + "title": "sculpt_nonmesh_and_paint_bounded_slices", + "kind": "feature", + "owner": "SCULPT", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P4-002" + ], + "parityId": "SCULPT.NONMESH.PAINT_BOUNDED", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-003.md", + "behavior": "Expose declared sculpt attributes/strokes, Curve/Surface/Font/PointCloud and paint slices with explicit PBVH limits.", + "outputs": [ + "non-mesh fixtures", + "stroke report", + "capability blocks" + ], + "acceptance": [ + "Main commit is atomic", + "unsupported brush/solver returns stable code", + "GPU/OOM/restart recovery passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-004", + "phase": "P4", + "title": "simulation_cache_identity_and_lifecycle", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P4-002", + "WBV2-P4-003" + ], + "parityId": "SIMULATION.CACHE_LIFECYCLE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G3", + "card": "docs/tasks/WBV2-P4-004.md", + "behavior": "Bind declared simulation cache to source/settings/revision hashes with cancellation, LRU and restart recovery.", + "outputs": [ + "cache fixtures", + "identity report", + "quarantine evidence" + ], + "acceptance": [ + "stale/corrupt cache never publishes", + "small cache recovers after restart", + "budget release is observable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-001", + "phase": "P5", + "title": "render_capability_routing", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P2-004", + "WBV2-P4-002", + "WBV2-P4-004" + ], + "parityId": "RENDER.ROUTING", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-001.md", + "behavior": "Route bounded Eevee/WebGL capabilities locally and unsupported render classes to SERVER_EXACT or EXCLUDED.", + "outputs": [ + "render receipts", + "pixel golden", + "routing report" + ], + "acceptance": [ + "source/settings/build identity bound", + "unsupported route cannot pretend local success", + "cancel/device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-002", + "phase": "P5", + "title": "compositor_sequencer_media_recovery", + "kind": "feature", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P3-002", + "WBV2-P5-001" + ], + "parityId": "MEDIA.BOUNDED_WORKFLOW", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-002.md", + "behavior": "Provide declared compositor/sequencer/codec/proxy/audio slices with revision and recovery gates.", + "outputs": [ + "media receipts", + "recovery report", + "audio/session diagnostics" + ], + "acceptance": [ + "seek/decode revision ordering", + "cancel/timeout does not publish", + "quota/OOM/restart leaves project valid" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-003", + "phase": "P5", + "title": "server_job_result_binding", + "kind": "feature", + "owner": "SERVER", + "dependsOn": [ + "WBV2-P0-003", + "WBV2-P5-001", + "WBV2-P5-002" + ], + "parityId": "SERVER.JOB_BINDING", + "implementationClass": "SERVER_EXACT", + "parallelGroup": "p5-server", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-003.md", + "behavior": "Bind server render/encode/physics jobs to immutable input/settings/build/output hashes and explicit lifecycle states.", + "outputs": [ + "server protocol", + "idempotency receipt", + "negative matrix" + ], + "acceptance": [ + "duplicate request is idempotent", + "stale result cannot bind", + "timeout/cancel/OOM produces no READY output" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-001", + "phase": "P6", + "title": "scripting_default_deny_and_audit", + "kind": "feature", + "owner": "SECURITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P5-003" + ], + "parityId": "SECURITY.SCRIPTING", + "implementationClass": "EXCLUDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-001.md", + "behavior": "Read text/metadata and expose audited, budgeted, default-deny script policy without arbitrary execution.", + "outputs": [ + "policy manifest", + "malicious fixtures", + "audit report" + ], + "acceptance": [ + "autorun/network/add-on defaults deny", + "sandbox cancellation/dispose works", + "no secret or filesystem escape" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-002", + "phase": "P6", + "title": "performance_fault_and_recovery_matrix", + "kind": "enabling", + "owner": "RELIABILITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P1-005", + "WBV2-P2-004", + "WBV2-P6-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-002.md", + "behavior": "Run deterministic geometry/texture/media/cache budgets and inject OOM/quota/device/network faults.", + "outputs": [ + "budget matrix", + "fault reports", + "resource release ledger" + ], + "acceptance": [ + "100k/1M/10M thresholds recorded", + "fault leaves old revision usable", + "all owned resources return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-003", + "phase": "P6", + "title": "offline_ci_sbom_and_rollback_release", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P6-001", + "WBV2-P6-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-release", + "gate": "G4", + "card": "docs/tasks/WBV2-P6-003.md", + "behavior": "Produce reproducible offline/source/binary release packages with CI lanes, SBOM and rollback evidence.", + "outputs": [ + "RC manifest", + "offline archive", + "CI reports" + ], + "acceptance": [ + "quick/Chromium/release lanes pass", + "artifact hashes reproduce", + "upgrade/rollback and known limitations are tested" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-001", + "phase": "P7", + "title": "cluster_full_blender_gap_inventory", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-002", + "WBV2-P6-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-001.md", + "behavior": "Cluster remaining Blender 5.2 data-block/operator/editor/node/format gaps by family and evidence class.", + "outputs": [ + "cluster catalog", + "coverage report", + "risk ranking" + ], + "acceptance": [ + "each gap has stable ID and owner", + "negative-only/unsupported is not positive parity", + "clusters are deterministic" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-002", + "phase": "P7", + "title": "generate_atomic_family_gap_queue", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-002.md", + "behavior": "Generate one task per parityId x observable behavior x implementation class with parent/hash context.", + "outputs": [ + "task index", + "task catalog", + "task cards" + ], + "acceptance": [ + "one active ready task", + "no guessed successor", + "each card fits context budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-003", + "phase": "P7", + "title": "full_parity_candidate_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P7-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P7-003.md", + "behavior": "Recompute parity closure, evidence health, recovery health and release decision from machine manifests.", + "outputs": [ + "parity release report", + "known limitations", + "final decision" + ], + "acceptance": [ + "all claims bind to evidence", + "blocked/excluded/server classes remain explicit", + "queue and protected hashes pass" + ], + "status": "blocked", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-000", + "phase": "P8", + "title": "authorize_recovery_capability_root", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-000.md", + "behavior": "Authorize a recovery epoch without rewriting the blocked P7 manifest.", + "outputs": [ + "recovery plan", + "root manifest", + "queue authorization" + ], + "acceptance": [ + "P7 evidence remains hash exact", + "recovery scope is explicit", + "one recovery task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P8-001", + "phase": "P8", + "title": "rebaseline_mutable_inventories", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-001.md", + "behavior": "Rebaseline mutable WBV2 plan and dependency inventory inputs while preserving historical manifests.", + "outputs": [ + "semantic drift report", + "current inventory baseline", + "manifest" + ], + "acceptance": [ + "only expected mutable hashes drift", + "dependency closure is unchanged", + "historical manifests remain unmodified" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-002", + "phase": "P8", + "title": "close_atomic_chromium_receipts", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P8-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-receipts", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-002.md", + "behavior": "Produce and bind all 45 atomic Chromium family receipts.", + "outputs": [ + "Chromium report", + "45 receipt index", + "receipt manifests" + ], + "acceptance": [ + "45 receipts are manifest-bound", + "desktop/WASM/save-reopen behaviors are explicit", + "Chromium is the only browser" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-003", + "phase": "P8", + "title": "authorize_m12_provenance_epoch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-provenance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-003.md", + "behavior": "Bind restored M12 sources and explicitly rebaseline unavailable originals in a new provenance epoch.", + "outputs": [ + "provenance epoch", + "replacement bindings", + "manifest" + ], + "acceptance": [ + "22 restored originals stay exact", + "62 unavailable entries are not called restored", + "all replacements are hash-bound" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-004", + "phase": "P8", + "title": "recompute_recovery_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P8-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-004.md", + "behavior": "Recompute the release decision from the recovery epoch and atomic receipts.", + "outputs": [ + "release gate", + "known limitations", + "final manifest" + ], + "acceptance": [ + "all receipts bind to manifests", + "provenance epoch is explicit", + "all governance gates pass" + ], + "status": "in_progress", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-000", + "phase": "P9", + "title": "authorize_feature_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-000.md", + "behavior": "Authorize feature parity continuation after provenance epoch 2 without claiming historical byte reproduction.", + "outputs": [ + "continuation receipt", + "feature parity plan", + "scope limits" + ], + "acceptance": [ + "P8 provenance evidence remains exact", + "authorized baseline is explicit", + "one feature task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P9-001", + "phase": "P9", + "title": "mesh_production_chromium_receipt", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P9-000" + ], + "parityId": "CAP-MESH-POSITIVE-EDIT", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-mesh", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-001.md", + "behavior": "Bind the existing Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt.", + "outputs": [ + "Chromium mesh receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real meshTranslateVertex command passes", + "desktop/WASM delta matches", + "save/reopen is exact", + "malformed/stale/unknown inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-002", + "phase": "P9", + "title": "modifier_production_chromium_receipt", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P9-001" + ], + "parityId": "CAP-MODIFIER-STATE-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-modifier", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-002.md", + "behavior": "Bind the existing Modifier Main transaction to a production Chromium receipt.", + "outputs": [ + "Chromium modifier receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real modifierSetEnabled command passes", + "desktop/WASM delta matches", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-003", + "phase": "P9", + "title": "asset_catalog_production_chromium_receipt", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P9-002" + ], + "parityId": "CAP-ASSET-CATALOG-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-asset", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-003.md", + "behavior": "Bind the existing Asset Catalog Main transaction and resource resolver to a production Chromium receipt.", + "outputs": [ + "Chromium asset receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real assetCatalogAppend command passes", + "resource hash is bound", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-004", + "phase": "P9", + "title": "recompute_feature_parity_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P9-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-release", + "gate": "G7", + "card": "docs/tasks/WBV2-P9-004.md", + "behavior": "Recompute declared feature parity claims from production Chromium receipts and authorized provenance.", + "outputs": [ + "feature parity gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only evidenced feature claims are emitted", + "authorized baseline remains explicit", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-000", + "phase": "P10", + "title": "authorize_native_engine_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P9-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-000.md", + "behavior": "Authorize native Blender/WASM engine parity continuation after bounded Chromium capability evidence.", + "outputs": [ + "continuation receipt", + "native parity plan", + "scope limits" + ], + "acceptance": [ + "P9 evidence remains hash-bound", + "native build/runtime is explicit", + "one native parity task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P10-001", + "phase": "P10", + "title": "reconcile_wbv2_inventory_source_drift", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-inventory", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-001.md", + "behavior": "Record the authorized mutable WBV2 plan drift and prove dependency closure stability without rewriting historical P0 evidence.", + "outputs": [ + "current source hash baseline", + "drift report", + "checker compatibility" + ], + "acceptance": [ + "historical P0 hashes remain unchanged", + "only authorized plan drift is recorded", + "dependency roots/lockfile/closure remain stable", + "inventory checker passes using current baseline" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-002", + "phase": "P10", + "title": "bind_native_and_wasm_engine_receipts", + "kind": "feature", + "owner": "ENGINE", + "dependsOn": [ + "WBV2-P10-001" + ], + "parityId": "ENGINE.NATIVE_WASM_BRIDGE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p10-engine", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-002.md", + "behavior": "Bind Mesh, Modifier, and Asset Catalog receipts to the compiled Blender native binary and web_engine.wasm runtime.", + "outputs": [ + "native receipt", + "WASM receipt", + "Chromium engine report" + ], + "acceptance": [ + "native Blender binary is source-bound", + "WASM binary and JS are hash-bound", + "same mutation reaches real engine/Main", + "save/reopen and failures remain exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-003", + "phase": "P10", + "title": "expand_core_module_operator_matrix", + "kind": "feature", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-002" + ], + "parityId": "CORE.MODULE_MATRIX", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-matrix", + "gate": "G7", + "card": "docs/tasks/WBV2-P10-003.md", + "behavior": "Expand the three proven capability modules with data-driven operator coverage and aggregate regression receipts.", + "outputs": [ + "module matrix", + "shard reports", + "aggregate manifest" + ], + "acceptance": [ + "positive cases are L2+", + "negative cases do not mutate Main", + "shards use one catalog hash", + "unmapped and retained-negative cases stay explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-000", + "phase": "P11", + "title": "authorize_module_expansion_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P10-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-governance", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-000.md", + "behavior": "Authorize deeper module production after real native/WASM engine binding and the first aggregate matrix.", + "outputs": [ + "continuation root", + "module expansion plan", + "scope limits" + ], + "acceptance": [ + "P10 evidence remains hash-bound", + "one expansion task is active", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P11-001", + "phase": "P11", + "title": "mesh_topology_operation_family", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P11-000" + ], + "parityId": "MESH.EDIT_TOPOLOGY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-mesh", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-001.md", + "behavior": "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real Blender WASM Main and preserve each result through save/reopen.", + "outputs": [ + "topology receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "six mesh operations mutate Main", + "revision increments exactly once", + "save/reopen preserves topology counts", + "invalid selection and incompatible configuration fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-002", + "phase": "P11", + "title": "modifier_parameter_apply_family", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P11-001" + ], + "parityId": "MODIFIER.PARAMETER_APPLY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-modifier", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-002.md", + "behavior": "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", + "outputs": [ + "modifier parameter receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "parameter mutation is native/WASM bound", + "apply result is evaluated", + "save/reopen is exact", + "dependency and stale inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-003", + "phase": "P11", + "title": "asset_link_override_reload_family", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P11-002" + ], + "parityId": "ASSET.LINK_OVERRIDE_RELOAD_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-asset", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-003.md", + "behavior": "Extend the real Asset Main path from append to link, override, reload, and missing-library boundaries.", + "outputs": [ + "asset ownership receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "source ownership is preserved", + "override is local and hash-bound", + "reload revision is checked", + "missing source remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-004", + "phase": "P11", + "title": "recompute_engine_module_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P11-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-release", + "gate": "G8", + "card": "docs/tasks/WBV2-P11-004.md", + "behavior": "Recompute engine-bound module parity from P10 and P11 receipts without claiming whole-inventory completion.", + "outputs": [ + "engine module gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only engine-bound claims are emitted", + "inventory remainder is explicit", + "provenance epoch 2 remains authorized rebaseline only", + "full historical reproduction remains false" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ], + "parentPlan": { + "path": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "sha256": "0f4750e45f2d1ca7d68faa35743e5b758ea8091f18d1d0e312ab548228d6f782" + }, + "recoveryRoot": "WBV2-P11-000", + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P11-002/module-expansion-task-plan.json", + "sha256": "8593eef68c7c8ba9fe772a37c84d6462d945220f0ebdb21a7cf981bd1f0f3fb0" + } +} diff --git a/tests/golden/WBV2-P11-003/task-context.json b/tests/golden/WBV2-P11-003/task-context.json new file mode 100644 index 000000000..eaa4859ec --- /dev/null +++ b/tests/golden/WBV2-P11-003/task-context.json @@ -0,0 +1,175 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-003", + "parentTask": "WBV2-P11-002", + "status": "in_progress", + "goal": "Extend the real Asset Main path from append to link, local override, reload, and missing-library boundaries.", + "scope": { + "gap": "workflow:asset_link_override_reload_family", + "ownerFamily": "ASSET", + "implementationClass": "LOCAL_EXACT" + }, + "commands": [ + "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-asset-link-override-production.spec.ts", + "node tools/web/generate-wbv2-asset-link-override-receipt.mjs --write", + "node tools/web/check-task-context.mjs --task WBV2-P11-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2022, + "contextRemainingTokens": 503 + }, + "source": { + "bytes": 7882, + "tokens": 1973 + }, + "selected": [], + "excluded": [ + { + "path": "tests/files/web/generated/WBV2-P3-005-ASSET.LIBRARY_OPERATIONS.blend", + "bytes": 85884, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/files/web/generated/WBV2P3005Library.blend", + "bytes": 90563, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "bytes": 3733, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P11-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P11-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P11-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "source ownership is preserved", + "override is local and hash-bound", + "reload revision is checked", + "missing source remains explicit" + ], + "nextTask": "WBV2-P11-004", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P11-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P11-002/manifest.json", + "parentStatus": "docs/status/WBV2-P11-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P11-003.md", + "tests/golden/WBV2-P11-002/manifest.json", + "docs/status/WBV2-P11-002.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-P11-002", + "parentTask": "WBV2-P11-001", + "status": "done", + "nextTask": "WBV2-P11-003", + "artifactCount": 14 + }, + "statusSummary": [ + "# WBV2-P11-002 status", + "- task: `WBV2-P11-002`; parent: `WBV2-P11-001`; status: `done`", + "- dependency preparation: all active modifiers disabled; revision: `1 -> 4`", + "- DECIMATE apply: revision `4 -> 5`; vertex/triangle counts reduced", + "- save/reopen: `EXACT`; stale profile and malformed ratio rejected", + "- nextTask: `WBV2-P11-003`", + "The bounded Modifier parameter/apply operation executes through the compiled WebEngine WASM Main. The dependency block is handled explicitly before apply; failed profile inputs leave the applied Main unchanged. This remains an engine-bound capability slice and does not claim complete modifier inventory parity or historical byte reproduction." + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1309, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 328 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P11-003.md", + "bytes": 1309, + "lines": 34, + "tokens": 328 + }, + { + "path": "tests/golden/WBV2-P11-002/manifest.json", + "bytes": 3101, + "lines": 80, + "tokens": 776 + }, + { + "path": "docs/status/WBV2-P11-002.md", + "bytes": 669, + "lines": 10, + "tokens": 168 + } + ], + "sourceTokens": 1973, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1973, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2997, + "serializedContextTokens": 666, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P11-004/engine-module-gate-report.json b/tests/golden/WBV2-P11-004/engine-module-gate-report.json new file mode 100644 index 000000000..109b9e8e0 --- /dev/null +++ b/tests/golden/WBV2-P11-004/engine-module-gate-report.json @@ -0,0 +1,98 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-004", + "operation": "RECOMPUTE_ENGINE_MODULE_PARITY_GATE", + "status": "PASS", + "decision": { + "status": "READY_WITH_ENGINE_MODULE_PARITY", + "code": "ENGINE_MODULE_PARITY_AUTHORIZED_REBASELINE", + "featureParityClaims": [ + "CAP-MESH-TOPOLOGY-FAMILY", + "CAP-MODIFIER-PARAMETER-APPLY", + "CAP-ASSET-LINK-OVERRIDE-RELOAD" + ], + "featureParityClaimCount": 3, + "engineBound": true, + "browser": "chromium", + "provenanceEpoch": 2, + "releaseScope": "AUTHORIZED_REBASELINE_ONLY", + "fullHistoricalReproduction": false, + "inventoryEntriesRemaining": 6900 + }, + "evidence": { + "engineReceipt": { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "sha256": "09c13b1814d61a6132ae1168d999e09b768915fe7fec652b6b965f9a6d3796f9", + "realNativeWasmMain": true + }, + "previousMatrix": { + "path": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json", + "sha256": "6d66635d900762809f82e73464ac298944514d25ac5172d2c697181cffeb7b8d", + "cases": 9, + "positive": 3, + "retainedNegative": 6 + }, + "modules": [ + { + "capabilityId": "CAP-MESH-TOPOLOGY-FAMILY", + "family": "MESH", + "manifest": "tests/golden/WBV2-P11-001/manifest.json", + "manifestSha256": "e08a02819065f1e7bc72a3bfae99e768c502dfa90af4b0614a701e7cca88b576", + "report": "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json", + "reportSha256": "5828fdde15d73bb1fb066bb05c35762f21471c1f52277903d39b4bdcc020f5f8", + "proof": "6 topology operations / 6 save-reopen exact", + "browser": "chromium", + "deterministic": true, + "saveReopen": "EXACT" + }, + { + "capabilityId": "CAP-MODIFIER-PARAMETER-APPLY", + "family": "MODIFIER", + "manifest": "tests/golden/WBV2-P11-002/manifest.json", + "manifestSha256": "32b9581bc0ef2cd3435a17c3b7d454ae5327ef8f0ac4c1916e9a0857eb42aaf1", + "report": "tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json", + "reportSha256": "339bf5007b04f81aecbd03a22791659895b2e78219cd5ee4031b890eb3120bc5", + "proof": "DECIMATE collapse apply / exact save-reopen", + "browser": "chromium", + "deterministic": true, + "saveReopen": "EXACT" + }, + { + "capabilityId": "CAP-ASSET-LINK-OVERRIDE-RELOAD", + "family": "ASSET_CATALOG", + "manifest": "tests/golden/WBV2-P11-003/manifest.json", + "manifestSha256": "da4c9414baaaab9a47c6cc6af66426450c640a99d781e4c0273e0189a72c047c", + "report": "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json", + "reportSha256": "d7eb0e3a0017fdb1780ba124c540e4967a01b7ea45303146b9ebc86327db48b9", + "proof": "ownership boundary / local append / exact save-reopen", + "browser": "chromium", + "deterministic": true, + "saveReopen": "EXACT" + } + ] + }, + "coverage": { + "moduleReceipts": 3, + "engineMutationReceipts": 3, + "inventoryTotal": 6900, + "inventoryClaimedComplete": 0, + "inventoryRemainingExplicit": 6900 + }, + "negative": { + "missingReceipt": "REJECTED", + "receiptHashDrift": "REJECTED", + "unsupportedBrowser": "REJECTED", + "nonExactSaveReopen": "REJECTED", + "falseInventoryCompletion": "REJECTED", + "falseHistoricalReproduction": "REJECTED", + "undeclaredCapabilityClaim": "REJECTED" + }, + "policy": { + "sourceHistoryReadOnly": true, + "authorizedRebaselineOnly": true, + "claimsEvidenceBound": true, + "inventoryRemainderExplicit": true, + "terminalQueuePointer": true + }, + "nextTask": null +} diff --git a/tests/golden/WBV2-P11-004/manifest.json b/tests/golden/WBV2-P11-004/manifest.json new file mode 100644 index 000000000..9d626c622 --- /dev/null +++ b/tests/golden/WBV2-P11-004/manifest.json @@ -0,0 +1,90 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-004", + "parentTask": "WBV2-P11-003", + "operation": "RECOMPUTE_ENGINE_MODULE_PARITY_GATE", + "status": "done", + "enablingTask": true, + "parityStateChange": true, + "runtime": "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P11-003/manifest.json", + "sha256": "da4c9414baaaab9a47c6cc6af66426450c640a99d781e4c0273e0189a72c047c" + }, + "approval": { + "path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", + "sha256": "cffc869734af94ffe6b8b8004d7ab8cc2c9edcb85ec2a877548e0b0f923f5ea3" + }, + "engineReceipt": { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "sha256": "09c13b1814d61a6132ae1168d999e09b768915fe7fec652b6b965f9a6d3796f9" + }, + "previousMatrix": { + "path": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json", + "sha256": "6d66635d900762809f82e73464ac298944514d25ac5172d2c697181cffeb7b8d" + }, + "inventory": { + "path": "tests/golden/WBV2-P0-002/parity-map.json", + "sha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8" + }, + "meshManifest": { + "path": "tests/golden/WBV2-P11-001/manifest.json", + "sha256": "e08a02819065f1e7bc72a3bfae99e768c502dfa90af4b0614a701e7cca88b576" + }, + "meshReport": { + "path": "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json", + "sha256": "5828fdde15d73bb1fb066bb05c35762f21471c1f52277903d39b4bdcc020f5f8" + }, + "modifierManifest": { + "path": "tests/golden/WBV2-P11-002/manifest.json", + "sha256": "32b9581bc0ef2cd3435a17c3b7d454ae5327ef8f0ac4c1916e9a0857eb42aaf1" + }, + "modifierReport": { + "path": "tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json", + "sha256": "339bf5007b04f81aecbd03a22791659895b2e78219cd5ee4031b890eb3120bc5" + }, + "assetManifest": { + "path": "tests/golden/WBV2-P11-003/manifest.json", + "sha256": "da4c9414baaaab9a47c6cc6af66426450c640a99d781e4c0273e0189a72c047c" + }, + "assetReport": { + "path": "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json", + "sha256": "d7eb0e3a0017fdb1780ba124c540e4967a01b7ea45303146b9ebc86327db48b9" + }, + "generator": { + "path": "tools/web/generate-wbv2-engine-module-gate.mjs", + "sha256": "f22a8053e183505ad45a8f182b03b99e46b06f21a11a43999b845f86f5149aeb" + }, + "report": { + "path": "tests/golden/WBV2-P11-004/engine-module-gate-report.json", + "sha256": "eec3f9efd085c3ff79ea502e334f297567ae6399194866addffcc703bc9579ab" + }, + "status": { + "path": "docs/status/WBV2-P11-004.md", + "sha256": "a834a3b63eef1611f35b93c4d6ff38fae2a45ff523ecebc005ee466ff5afc546" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P11-004/module-expansion-task-plan.json", + "sha256": "185f2412fd651068346230cc945973e078cfa642da2cb6f5f51943e306b40d57" + }, + "taskContext": { + "path": "tests/golden/WBV2-P11-004/task-context.json", + "sha256": "bc6e68dd107bf143c8421b4ff165b01323bd18277f9e70b5c81dbc56ddbed4df" + } + }, + "assertions": { + "engineBoundClaims": 3, + "meshTopologyOperations": 6, + "modifierApply": true, + "assetOwnershipBoundary": true, + "exactSaveReopenReceipts": 3, + "inventoryEntriesRemaining": 6900, + "inventoryClaimedComplete": 0, + "provenanceEpoch": 2, + "authorizedRebaselineOnly": true, + "fullHistoricalReproduction": false, + "deterministic": true + }, + "nextTask": null +} diff --git a/tests/golden/WBV2-P11-004/module-expansion-task-plan.json b/tests/golden/WBV2-P11-004/module-expansion-task-plan.json new file mode 100644 index 000000000..3a4b17efc --- /dev/null +++ b/tests/golden/WBV2-P11-004/module-expansion-task-plan.json @@ -0,0 +1,1716 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_MODULE_EXPANSION_EPOCH_1", + "status": "COMPLETED_WITH_ENGINE_MODULE_PARITY", + "authority": "queue_reactivated_after_p10_engine_matrix", + "productContract": "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", + "sourcePlan": "docs/BLENDER_5_2_FULL_WEB_PARITY_EXECUTION_PLAN.md", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "correctiveCheckpoint": { + "task": "C6-003", + "handoff": "tests/golden/corrective/C6-003/handoff.json", + "status": "active", + "blocker": null, + "queueMutation": true, + "legacyTask": "M16-GAP-00277", + "legacyParentNextTask": "M16-GAP-00277" + }, + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "storage": [ + "opfs", + "indexeddb" + ], + "queueMutation": "enabled_after_owner_review_and_g5" + }, + "completionClasses": [ + "LOCAL_EXACT", + "LOCAL_BOUNDED", + "SERVER_EXACT", + "EXCLUDED" + ], + "gates": [ + { + "id": "G0", + "name": "scope_and_inventory", + "requires": [ + "contract", + "inventory", + "capability_matrix" + ] + }, + { + "id": "G1", + "name": "runtime_foundation", + "requires": [ + "sceneir", + "main_transaction", + "worker_lifecycle", + "storage_journal" + ] + }, + { + "id": "G2", + "name": "feature_parity", + "requires": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence" + ] + }, + { + "id": "G3", + "name": "recovery_and_security", + "requires": [ + "cancel", + "restart", + "oom_quota", + "malformed", + "dispose" + ] + }, + { + "id": "G4", + "name": "release_candidate", + "requires": [ + "offline", + "ci", + "sbom", + "rollback", + "hashes" + ] + }, + { + "id": "G5", + "name": "queue_mutation", + "requires": [ + "owner_review", + "protected_hashes", + "handoff", + "single_ready_task" + ] + } + ], + "waves": [ + { + "id": "P0", + "name": "facts_and_contracts", + "gate": "G0", + "tasks": [ + "WBV2-P0-001", + "WBV2-P0-002", + "WBV2-P0-003" + ] + }, + { + "id": "P1", + "name": "runtime_foundation", + "gate": "G1", + "tasks": [ + "WBV2-P1-001", + "WBV2-P1-002", + "WBV2-P1-003", + "WBV2-P1-004", + "WBV2-P1-005" + ] + }, + { + "id": "P2", + "name": "core_modeler_loop", + "gate": "G2", + "tasks": [ + "WBV2-P2-001", + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P2-005" + ] + }, + { + "id": "P3", + "name": "authoring_and_io", + "gate": "G2", + "tasks": [ + "WBV2-P3-001", + "WBV2-P3-002", + "WBV2-P3-003", + "WBV2-P3-004", + "WBV2-P3-005" + ] + }, + { + "id": "P4", + "name": "advanced_local_slices", + "gate": "G2", + "tasks": [ + "WBV2-P4-001", + "WBV2-P4-002", + "WBV2-P4-003", + "WBV2-P4-004" + ] + }, + { + "id": "P5", + "name": "render_and_server", + "gate": "G3", + "tasks": [ + "WBV2-P5-001", + "WBV2-P5-002", + "WBV2-P5-003" + ] + }, + { + "id": "P6", + "name": "security_performance_release", + "gate": "G4", + "tasks": [ + "WBV2-P6-001", + "WBV2-P6-002", + "WBV2-P6-003" + ] + }, + { + "id": "P7", + "name": "full_parity_gap_program", + "gate": "G5", + "tasks": [ + "WBV2-P7-001", + "WBV2-P7-002", + "WBV2-P7-003" + ] + } + ], + "taskContract": { + "onePrimaryBehavior": true, + "requiredEvidence": [ + "desktop", + "wasm_main", + "chromium", + "negative", + "persistence", + "manifest", + "status" + ], + "requiredCommands": [ + "focused", + "determinism", + "hash", + "governance" + ], + "failureState": "in_progress_or_blocked", + "successorRule": "only_from_parent_manifest_nextTask" + }, + "tasks": [ + { + "id": "WBV2-P0-001", + "phase": "P0", + "title": "reconcile_scope_and_checkpoints", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-governance", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-001.md", + "behavior": "Freeze V1/full-parity boundary and reconcile legacy/corrective pointers without queue mutation.", + "outputs": [ + "scope decision", + "checkpoint report", + "protected hash set" + ], + "acceptance": [ + "corrective owner-review status is explicit", + "legacy parent pointer is unchanged", + "plan has one activation gate" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-002", + "phase": "P0", + "title": "generate_blender52_inventory_and_parity_map", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-inventory", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-002.md", + "behavior": "Generate stable Blender 5.2 data-block/operator/editor/node/format inventory and map every entry to a completion class.", + "outputs": [ + "inventory", + "parity map", + "source hash" + ], + "acceptance": [ + "unknown entries are classified", + "inventory is deterministic", + "no entry claims feature parity without evidence" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P0-003", + "phase": "P0", + "title": "freeze_capability_error_budget_contract", + "kind": "enabling", + "owner": "PROTOCOL", + "dependsOn": [ + "WBV2-P0-001", + "WBV2-P0-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p0-contract", + "gate": "G0", + "card": "docs/tasks/WBV2-P0-003.md", + "behavior": "Freeze capability levels, stable error codes, revision, budget, cancellation and loss-report schemas.", + "outputs": [ + "versioned protocol", + "capability matrix", + "negative matrix" + ], + "acceptance": [ + "unsupported input fails closed", + "schema hashes are stable", + "migration policy preserves unknown data" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-001", + "phase": "P1", + "title": "stabilize_runtime_variants_and_source_receipts", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P0-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-runtime", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-001.md", + "behavior": "Bind single-thread/pthread WebEngine variants to pinned Blender source/build/runtime receipts.", + "outputs": [ + "runtime manifest", + "variant selector", + "fallback report" + ], + "acceptance": [ + "variant fallback is deterministic", + "source/build hash is verified", + "one engine session has one generation" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-002", + "phase": "P1", + "title": "unify_sceneir_stable_ids_and_binary_deltas", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-001" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-sceneir", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-002.md", + "behavior": "Make SceneIR/WBG1 stable IDs, topology/attribute domains and binary/range deltas canonical across desktop and WASM.", + "outputs": [ + "SceneIR schema", + "binary fixture", + "delta comparator" + ], + "acceptance": [ + "IDs survive save/reopen", + "malformed chunk is rejected", + "desktop and WASM canonical hashes match" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-003", + "phase": "P1", + "title": "unify_main_transaction_history_and_save", + "kind": "enabling", + "owner": "MAIN", + "dependsOn": [ + "WBV2-P1-002" + ], + "parityId": null, + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p1-history", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-003.md", + "behavior": "Use one Main transaction/revision/history contract for commit, undo/redo, atomic save and reopen.", + "outputs": [ + "transaction contract", + "history receipt", + "save/reopen runner" + ], + "acceptance": [ + "failed/no-op commands add no history", + "stale revision cannot commit", + "reopen state is byte/hash stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-004", + "phase": "P1", + "title": "harden_worker_cancel_restart_and_dispose", + "kind": "enabling", + "owner": "RUNTIME", + "dependsOn": [ + "WBV2-P1-001", + "WBV2-P1-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-lifecycle", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-004.md", + "behavior": "Make cancellation, late-result rejection, Worker restart and resource disposal common to all domains.", + "outputs": [ + "lifecycle runner", + "fault report", + "dispose counters" + ], + "acceptance": [ + "cancel never publishes result", + "generation mismatch is rejected", + "CPU/WASM/GPU owners return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P1-005", + "phase": "P1", + "title": "harden_opfs_indexeddb_journal_recovery", + "kind": "enabling", + "owner": "STORAGE", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P1-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p1-storage", + "gate": "G1", + "card": "docs/tasks/WBV2-P1-005.md", + "behavior": "Unify OPFS staging/content addressing and IndexedDB metadata/journal recovery.", + "outputs": [ + "storage schema", + "crash fixtures", + "recovery checker" + ], + "acceptance": [ + "interrupted commit leaves old project usable", + "hash mismatch quarantines payload", + "small project recovers after restart" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-001", + "phase": "P2", + "title": "open_blend_scene_context_and_outliner", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P1-005" + ], + "parityId": "EDITOR.OPEN_SCENE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-editor", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-001.md", + "behavior": "Open a minimal .blend and expose scene/object/collection context from authoritative Main.", + "outputs": [ + "desktop fixture", + "outliner report", + "Chromium path" + ], + "acceptance": [ + "stable IDs and selection revision match", + "missing data is structured", + "reopen preserves context" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-002", + "phase": "P2", + "title": "object_collection_parent_transform_workflow", + "kind": "feature", + "owner": "EDITOR", + "dependsOn": [ + "WBV2-P1-003", + "WBV2-P2-001" + ], + "parityId": "OBJECT.TRANSFORM_HIERARCHY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-scene", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-002.md", + "behavior": "Edit object transform, collection membership and parent hierarchy through Main transactions.", + "outputs": [ + "desktop/WASM golden", + "negative cases", + "save/reopen receipt" + ], + "acceptance": [ + "world matrix parity", + "cycle/locked/library edits reject", + "undo/redo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-003", + "phase": "P2", + "title": "mesh_edit_core_operations", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P1-002", + "WBV2-P2-002" + ], + "parityId": "MESH.EDIT_CORE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p2-mesh", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-003.md", + "behavior": "Expose bounded vertex/edge/face selection plus merge/dissolve/extrude/inset/bevel/loop-cut.", + "outputs": [ + "Blender fixture set", + "topology comparator", + "Chromium edit path" + ], + "acceptance": [ + "topology/attributes match", + "invalid selection and budget fail closed", + "single transaction and reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-004", + "phase": "P2", + "title": "dual_viewport_sceneir_render_path", + "kind": "feature", + "owner": "VIEWPORT", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P2-003" + ], + "parityId": "VIEWPORT.MAIN_OFFSCREEN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-viewport", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-004.md", + "behavior": "Render the same validated SceneIR through main-thread WebGL2 and OffscreenCanvas Worker paths.", + "outputs": [ + "pixel report", + "viewport diagnostics", + "device recovery" + ], + "acceptance": [ + "both paths have nonblank pixels", + "selection/camera revision is shared", + "device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P2-005", + "phase": "P2", + "title": "close_p0_user_loop", + "kind": "feature", + "owner": "INTEGRATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-003", + "WBV2-P1-005", + "WBV2-P2-004" + ], + "parityId": "WORKFLOW.P0_USER_LOOP", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p2-integration", + "gate": "G2", + "card": "docs/tasks/WBV2-P2-005.md", + "behavior": "Prove open -> edit -> undo -> redo -> save -> restart -> reopen -> GLB in one production flow.", + "outputs": [ + "P0 workflow report", + "release binding", + "rollback receipt" + ], + "acceptance": [ + "Main revision and exported asset are bound", + "fault/cancel leaves old state", + "Chromium production path passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-001", + "phase": "P3", + "title": "material_uv_principled_asset_workflow", + "kind": "feature", + "owner": "MATERIAL", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005" + ], + "parityId": "MATERIAL.PBR_UV", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-001.md", + "behavior": "Edit material slots, UVs and declared Principled/Image/Normal graph nodes with content-addressed textures.", + "outputs": [ + "material golden", + "texture receipt", + "loss report" + ], + "acceptance": [ + "desktop/WASM node fields match", + "unsupported node retained/blocked", + "packed asset survives reopen" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-002", + "phase": "P3", + "title": "keyframe_timeline_action_workflow", + "kind": "feature", + "owner": "ANIMATION", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P2-005", + "WBV2-P3-001" + ], + "parityId": "ANIMATION.TRS_ACTION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-authoring", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-002.md", + "behavior": "Create/edit TRS keyframes, timeline and declared Action interpolation through Main.", + "outputs": [ + "frame golden", + "animation comparator", + "reopen report" + ], + "acceptance": [ + "sampled values and handles match", + "stale frame result rejected", + "undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-003", + "phase": "P3", + "title": "armature_pose_constraint_skin_workflow", + "kind": "feature", + "owner": "RIG", + "dependsOn": [ + "WBV2-P2-002", + "WBV2-P3-002" + ], + "parityId": "RIG.POSE_SKIN", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-rig", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-003.md", + "behavior": "Read and edit declared armature pose/constraint/weight/shape-key slices with bounded evaluation.", + "outputs": [ + "pose golden", + "skin report", + "unsupported matrix" + ], + "acceptance": [ + "pose matrices and weights match", + "unsupported constraint is explicit", + "save/reopen and small recovery pass" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-004", + "phase": "P3", + "title": "glb_roundtrip_and_loss_report", + "kind": "feature", + "owner": "IO", + "dependsOn": [ + "WBV2-P2-005", + "WBV2-P3-001", + "WBV2-P3-003" + ], + "parityId": "IO.GLB_ROUNDTRIP", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p3-io", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-004.md", + "behavior": "Import/export declared GLB mesh/PBR/texture/morph/skin/animation and report non-mapped semantics.", + "outputs": [ + "GLB fixtures", + "desktop reimport report", + "loss report" + ], + "acceptance": [ + "roundtrip canonical graph matches", + "sparse/external URI/budget negatives reject", + "no silent loss" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P3-005", + "phase": "P3", + "title": "library_asset_append_link_override", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P2-001", + "WBV2-P3-004" + ], + "parityId": "ASSET.LIBRARY_OPERATIONS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p3-assets", + "gate": "G2", + "card": "docs/tasks/WBV2-P3-005.md", + "behavior": "Support declared append/link/override ownership, reload and missing-library semantics.", + "outputs": [ + "library fixtures", + "ownership report", + "negative matrix" + ], + "acceptance": [ + "source/hash/owner identity preserved", + "linked mutation blocked", + "stale generation and missing source fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-001", + "phase": "P4", + "title": "modifier_graph_and_apply_slices", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-005", + "WBV2-P3-005" + ], + "parityId": "MODIFIER.DECLARED_SLICES", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-001.md", + "behavior": "Enable one declared modifier parameter/apply workflow at a time with dependency-aware blocking.", + "outputs": [ + "modifier goldens", + "dependency report", + "negative cases" + ], + "acceptance": [ + "desktop/evaluated Main match", + "unknown modifier retained and blocked", + "apply/undo/save/reopen stable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-002", + "phase": "P4", + "title": "geometry_nodes_and_shader_allowlist", + "kind": "feature", + "owner": "NODES", + "dependsOn": [ + "WBV2-P3-001", + "WBV2-P4-001" + ], + "parityId": "NODES.ALLOWLIST", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-002.md", + "behavior": "Read/write/evaluate only declared Geometry Nodes and shader graph allowlists with resource budgets.", + "outputs": [ + "node fixtures", + "compile/cache receipts", + "unsupported graph reports" + ], + "acceptance": [ + "node/socket/link/default parity", + "budget and unknown-node block before commit", + "compile failure rolls back" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-003", + "phase": "P4", + "title": "sculpt_nonmesh_and_paint_bounded_slices", + "kind": "feature", + "owner": "SCULPT", + "dependsOn": [ + "WBV2-P2-003", + "WBV2-P2-004", + "WBV2-P4-002" + ], + "parityId": "SCULPT.NONMESH.PAINT_BOUNDED", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G2", + "card": "docs/tasks/WBV2-P4-003.md", + "behavior": "Expose declared sculpt attributes/strokes, Curve/Surface/Font/PointCloud and paint slices with explicit PBVH limits.", + "outputs": [ + "non-mesh fixtures", + "stroke report", + "capability blocks" + ], + "acceptance": [ + "Main commit is atomic", + "unsupported brush/solver returns stable code", + "GPU/OOM/restart recovery passes" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P4-004", + "phase": "P4", + "title": "simulation_cache_identity_and_lifecycle", + "kind": "feature", + "owner": "SIMULATION", + "dependsOn": [ + "WBV2-P1-005", + "WBV2-P4-002", + "WBV2-P4-003" + ], + "parityId": "SIMULATION.CACHE_LIFECYCLE", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p4-domains", + "gate": "G3", + "card": "docs/tasks/WBV2-P4-004.md", + "behavior": "Bind declared simulation cache to source/settings/revision hashes with cancellation, LRU and restart recovery.", + "outputs": [ + "cache fixtures", + "identity report", + "quarantine evidence" + ], + "acceptance": [ + "stale/corrupt cache never publishes", + "small cache recovers after restart", + "budget release is observable" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-001", + "phase": "P5", + "title": "render_capability_routing", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P2-004", + "WBV2-P4-002", + "WBV2-P4-004" + ], + "parityId": "RENDER.ROUTING", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-001.md", + "behavior": "Route bounded Eevee/WebGL capabilities locally and unsupported render classes to SERVER_EXACT or EXCLUDED.", + "outputs": [ + "render receipts", + "pixel golden", + "routing report" + ], + "acceptance": [ + "source/settings/build identity bound", + "unsupported route cannot pretend local success", + "cancel/device loss releases resources" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-002", + "phase": "P5", + "title": "compositor_sequencer_media_recovery", + "kind": "feature", + "owner": "MEDIA", + "dependsOn": [ + "WBV2-P3-002", + "WBV2-P5-001" + ], + "parityId": "MEDIA.BOUNDED_WORKFLOW", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p5-media", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-002.md", + "behavior": "Provide declared compositor/sequencer/codec/proxy/audio slices with revision and recovery gates.", + "outputs": [ + "media receipts", + "recovery report", + "audio/session diagnostics" + ], + "acceptance": [ + "seek/decode revision ordering", + "cancel/timeout does not publish", + "quota/OOM/restart leaves project valid" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P5-003", + "phase": "P5", + "title": "server_job_result_binding", + "kind": "feature", + "owner": "SERVER", + "dependsOn": [ + "WBV2-P0-003", + "WBV2-P5-001", + "WBV2-P5-002" + ], + "parityId": "SERVER.JOB_BINDING", + "implementationClass": "SERVER_EXACT", + "parallelGroup": "p5-server", + "gate": "G3", + "card": "docs/tasks/WBV2-P5-003.md", + "behavior": "Bind server render/encode/physics jobs to immutable input/settings/build/output hashes and explicit lifecycle states.", + "outputs": [ + "server protocol", + "idempotency receipt", + "negative matrix" + ], + "acceptance": [ + "duplicate request is idempotent", + "stale result cannot bind", + "timeout/cancel/OOM produces no READY output" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-001", + "phase": "P6", + "title": "scripting_default_deny_and_audit", + "kind": "feature", + "owner": "SECURITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P5-003" + ], + "parityId": "SECURITY.SCRIPTING", + "implementationClass": "EXCLUDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-001.md", + "behavior": "Read text/metadata and expose audited, budgeted, default-deny script policy without arbitrary execution.", + "outputs": [ + "policy manifest", + "malicious fixtures", + "audit report" + ], + "acceptance": [ + "autorun/network/add-on defaults deny", + "sandbox cancellation/dispose works", + "no secret or filesystem escape" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-002", + "phase": "P6", + "title": "performance_fault_and_recovery_matrix", + "kind": "enabling", + "owner": "RELIABILITY", + "dependsOn": [ + "WBV2-P1-004", + "WBV2-P1-005", + "WBV2-P2-004", + "WBV2-P6-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-safety", + "gate": "G3", + "card": "docs/tasks/WBV2-P6-002.md", + "behavior": "Run deterministic geometry/texture/media/cache budgets and inject OOM/quota/device/network faults.", + "outputs": [ + "budget matrix", + "fault reports", + "resource release ledger" + ], + "acceptance": [ + "100k/1M/10M thresholds recorded", + "fault leaves old revision usable", + "all owned resources return to budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P6-003", + "phase": "P6", + "title": "offline_ci_sbom_and_rollback_release", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P6-001", + "WBV2-P6-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p6-release", + "gate": "G4", + "card": "docs/tasks/WBV2-P6-003.md", + "behavior": "Produce reproducible offline/source/binary release packages with CI lanes, SBOM and rollback evidence.", + "outputs": [ + "RC manifest", + "offline archive", + "CI reports" + ], + "acceptance": [ + "quick/Chromium/release lanes pass", + "artifact hashes reproduce", + "upgrade/rollback and known limitations are tested" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-001", + "phase": "P7", + "title": "cluster_full_blender_gap_inventory", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P0-002", + "WBV2-P6-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-001.md", + "behavior": "Cluster remaining Blender 5.2 data-block/operator/editor/node/format gaps by family and evidence class.", + "outputs": [ + "cluster catalog", + "coverage report", + "risk ranking" + ], + "acceptance": [ + "each gap has stable ID and owner", + "negative-only/unsupported is not positive parity", + "clusters are deterministic" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-002", + "phase": "P7", + "title": "generate_atomic_family_gap_queue", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-gap", + "gate": "G4", + "card": "docs/tasks/WBV2-P7-002.md", + "behavior": "Generate one task per parityId x observable behavior x implementation class with parent/hash context.", + "outputs": [ + "task index", + "task catalog", + "task cards" + ], + "acceptance": [ + "one active ready task", + "no guessed successor", + "each card fits context budget" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P7-003", + "phase": "P7", + "title": "full_parity_candidate_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P7-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p7-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P7-003.md", + "behavior": "Recompute parity closure, evidence health, recovery health and release decision from machine manifests.", + "outputs": [ + "parity release report", + "known limitations", + "final decision" + ], + "acceptance": [ + "all claims bind to evidence", + "blocked/excluded/server classes remain explicit", + "queue and protected hashes pass" + ], + "status": "blocked", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-000", + "phase": "P8", + "title": "authorize_recovery_capability_root", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P7-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-000.md", + "behavior": "Authorize a recovery epoch without rewriting the blocked P7 manifest.", + "outputs": [ + "recovery plan", + "root manifest", + "queue authorization" + ], + "acceptance": [ + "P7 evidence remains hash exact", + "recovery scope is explicit", + "one recovery task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P8-001", + "phase": "P8", + "title": "rebaseline_mutable_inventories", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-governance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-001.md", + "behavior": "Rebaseline mutable WBV2 plan and dependency inventory inputs while preserving historical manifests.", + "outputs": [ + "semantic drift report", + "current inventory baseline", + "manifest" + ], + "acceptance": [ + "only expected mutable hashes drift", + "dependency closure is unchanged", + "historical manifests remain unmodified" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-002", + "phase": "P8", + "title": "close_atomic_chromium_receipts", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P8-001" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-receipts", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-002.md", + "behavior": "Produce and bind all 45 atomic Chromium family receipts.", + "outputs": [ + "Chromium report", + "45 receipt index", + "receipt manifests" + ], + "acceptance": [ + "45 receipts are manifest-bound", + "desktop/WASM/save-reopen behaviors are explicit", + "Chromium is the only browser" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-003", + "phase": "P8", + "title": "authorize_m12_provenance_epoch", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-provenance", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-003.md", + "behavior": "Bind restored M12 sources and explicitly rebaseline unavailable originals in a new provenance epoch.", + "outputs": [ + "provenance epoch", + "replacement bindings", + "manifest" + ], + "acceptance": [ + "22 restored originals stay exact", + "62 unavailable entries are not called restored", + "all replacements are hash-bound" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P8-004", + "phase": "P8", + "title": "recompute_recovery_release_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P8-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p8-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P8-004.md", + "behavior": "Recompute the release decision from the recovery epoch and atomic receipts.", + "outputs": [ + "release gate", + "known limitations", + "final manifest" + ], + "acceptance": [ + "all receipts bind to manifests", + "provenance epoch is explicit", + "all governance gates pass" + ], + "status": "in_progress", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-000", + "phase": "P9", + "title": "authorize_feature_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P8-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-000.md", + "behavior": "Authorize feature parity continuation after provenance epoch 2 without claiming historical byte reproduction.", + "outputs": [ + "continuation receipt", + "feature parity plan", + "scope limits" + ], + "acceptance": [ + "P8 provenance evidence remains exact", + "authorized baseline is explicit", + "one feature task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P9-001", + "phase": "P9", + "title": "mesh_production_chromium_receipt", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P9-000" + ], + "parityId": "CAP-MESH-POSITIVE-EDIT", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-mesh", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-001.md", + "behavior": "Bind the existing Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt.", + "outputs": [ + "Chromium mesh receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real meshTranslateVertex command passes", + "desktop/WASM delta matches", + "save/reopen is exact", + "malformed/stale/unknown inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-002", + "phase": "P9", + "title": "modifier_production_chromium_receipt", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P9-001" + ], + "parityId": "CAP-MODIFIER-STATE-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-modifier", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-002.md", + "behavior": "Bind the existing Modifier Main transaction to a production Chromium receipt.", + "outputs": [ + "Chromium modifier receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real modifierSetEnabled command passes", + "desktop/WASM delta matches", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-003", + "phase": "P9", + "title": "asset_catalog_production_chromium_receipt", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P9-002" + ], + "parityId": "CAP-ASSET-CATALOG-MUTATION", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p9-asset", + "gate": "G6", + "card": "docs/tasks/WBV2-P9-003.md", + "behavior": "Bind the existing Asset Catalog Main transaction and resource resolver to a production Chromium receipt.", + "outputs": [ + "Chromium asset receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "real assetCatalogAppend command passes", + "resource hash is bound", + "save/reopen is exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P9-004", + "phase": "P9", + "title": "recompute_feature_parity_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P9-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p9-release", + "gate": "G7", + "card": "docs/tasks/WBV2-P9-004.md", + "behavior": "Recompute declared feature parity claims from production Chromium receipts and authorized provenance.", + "outputs": [ + "feature parity gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only evidenced feature claims are emitted", + "authorized baseline remains explicit", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-000", + "phase": "P10", + "title": "authorize_native_engine_parity_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P9-004" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-governance", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-000.md", + "behavior": "Authorize native Blender/WASM engine parity continuation after bounded Chromium capability evidence.", + "outputs": [ + "continuation receipt", + "native parity plan", + "scope limits" + ], + "acceptance": [ + "P9 evidence remains hash-bound", + "native build/runtime is explicit", + "one native parity task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P10-001", + "phase": "P10", + "title": "reconcile_wbv2_inventory_source_drift", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-000" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-inventory", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-001.md", + "behavior": "Record the authorized mutable WBV2 plan drift and prove dependency closure stability without rewriting historical P0 evidence.", + "outputs": [ + "current source hash baseline", + "drift report", + "checker compatibility" + ], + "acceptance": [ + "historical P0 hashes remain unchanged", + "only authorized plan drift is recorded", + "dependency roots/lockfile/closure remain stable", + "inventory checker passes using current baseline" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-002", + "phase": "P10", + "title": "bind_native_and_wasm_engine_receipts", + "kind": "feature", + "owner": "ENGINE", + "dependsOn": [ + "WBV2-P10-001" + ], + "parityId": "ENGINE.NATIVE_WASM_BRIDGE", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p10-engine", + "gate": "G6", + "card": "docs/tasks/WBV2-P10-002.md", + "behavior": "Bind Mesh, Modifier, and Asset Catalog receipts to the compiled Blender native binary and web_engine.wasm runtime.", + "outputs": [ + "native receipt", + "WASM receipt", + "Chromium engine report" + ], + "acceptance": [ + "native Blender binary is source-bound", + "WASM binary and JS are hash-bound", + "same mutation reaches real engine/Main", + "save/reopen and failures remain exact" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P10-003", + "phase": "P10", + "title": "expand_core_module_operator_matrix", + "kind": "feature", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P10-002" + ], + "parityId": "CORE.MODULE_MATRIX", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p10-matrix", + "gate": "G7", + "card": "docs/tasks/WBV2-P10-003.md", + "behavior": "Expand the three proven capability modules with data-driven operator coverage and aggregate regression receipts.", + "outputs": [ + "module matrix", + "shard reports", + "aggregate manifest" + ], + "acceptance": [ + "positive cases are L2+", + "negative cases do not mutate Main", + "shards use one catalog hash", + "unmapped and retained-negative cases stay explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-000", + "phase": "P11", + "title": "authorize_module_expansion_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P10-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-governance", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-000.md", + "behavior": "Authorize deeper module production after real native/WASM engine binding and the first aggregate matrix.", + "outputs": [ + "continuation root", + "module expansion plan", + "scope limits" + ], + "acceptance": [ + "P10 evidence remains hash-bound", + "one expansion task is active", + "full historical reproduction remains false" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P11-001", + "phase": "P11", + "title": "mesh_topology_operation_family", + "kind": "feature", + "owner": "MESH", + "dependsOn": [ + "WBV2-P11-000" + ], + "parityId": "MESH.EDIT_TOPOLOGY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-mesh", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-001.md", + "behavior": "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real Blender WASM Main and preserve each result through save/reopen.", + "outputs": [ + "topology receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "six mesh operations mutate Main", + "revision increments exactly once", + "save/reopen preserves topology counts", + "invalid selection and incompatible configuration fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-002", + "phase": "P11", + "title": "modifier_parameter_apply_family", + "kind": "feature", + "owner": "MODIFIER", + "dependsOn": [ + "WBV2-P11-001" + ], + "parityId": "MODIFIER.PARAMETER_APPLY_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-modifier", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-002.md", + "behavior": "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", + "outputs": [ + "modifier parameter receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "parameter mutation is native/WASM bound", + "apply result is evaluated", + "save/reopen is exact", + "dependency and stale inputs fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-003", + "phase": "P11", + "title": "asset_link_override_reload_family", + "kind": "feature", + "owner": "ASSET", + "dependsOn": [ + "WBV2-P11-002" + ], + "parityId": "ASSET.LINK_OVERRIDE_RELOAD_FAMILY", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p11-asset", + "gate": "G7", + "card": "docs/tasks/WBV2-P11-003.md", + "behavior": "Extend the real Asset Main path from append to link, override, reload, and missing-library boundaries.", + "outputs": [ + "asset ownership receipt", + "negative matrix", + "manifest" + ], + "acceptance": [ + "source ownership is preserved", + "override is local and hash-bound", + "reload revision is checked", + "missing source remains explicit" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P11-004", + "phase": "P11", + "title": "recompute_engine_module_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P11-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p11-release", + "gate": "G8", + "card": "docs/tasks/WBV2-P11-004.md", + "behavior": "Recompute engine-bound module parity from P10 and P11 receipts without claiming whole-inventory completion.", + "outputs": [ + "engine module gate", + "limited release declaration", + "manifest" + ], + "acceptance": [ + "only engine-bound claims are emitted", + "inventory remainder is explicit", + "provenance epoch 2 remains authorized rebaseline only", + "full historical reproduction remains false" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ], + "parentPlan": { + "path": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "sha256": "0f4750e45f2d1ca7d68faa35743e5b758ea8091f18d1d0e312ab548228d6f782" + }, + "recoveryRoot": "WBV2-P11-000", + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P11-003/module-expansion-task-plan.json", + "sha256": "d4c7be339c4b0455d82b4f4c4baab6a4f47909883b9da3c1de9e61ea8001b898" + } +} diff --git a/tests/golden/WBV2-P11-004/task-context.json b/tests/golden/WBV2-P11-004/task-context.json new file mode 100644 index 000000000..c77e9928d --- /dev/null +++ b/tests/golden/WBV2-P11-004/task-context.json @@ -0,0 +1,177 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P11-004", + "parentTask": "WBV2-P11-003", + "status": "in_progress", + "goal": "Recompute engine-bound module claims from P10 and P11 receipts without claiming whole-inventory completion.", + "scope": { + "gap": "workflow:recompute_engine_module_gate", + "ownerFamily": "RELEASE", + "implementationClass": "LOCAL_BOUNDED" + }, + "commands": [ + "node tools/web/generate-wbv2-engine-module-gate.mjs --write", + "node tools/web/check-task-context.mjs --task WBV2-P11-004 --write" + ], + "inputPaths": [ + "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json" + ], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2160, + "contextRemainingTokens": 539 + }, + "source": { + "bytes": 7744, + "tokens": 1937 + }, + "selected": [ + { + "path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", + "bytes": 704, + "tokens": 176 + } + ], + "excluded": [ + { + "path": "tests/golden/WBV2-P10-002/native-engine-receipt-report.json", + "bytes": 3733, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json", + "bytes": 2351, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P11-004/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P11-004.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P11-004/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 1, + "bytes": 704, + "tokens": 176 + } + }, + "exitCriteria": [ + "only engine-bound claims are emitted", + "inventory remainder is explicit", + "provenance epoch 2 remains authorized rebaseline only", + "full historical reproduction remains false" + ], + "nextTask": null, + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P11-004.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P11-003/manifest.json", + "parentStatus": "docs/status/WBV2-P11-003.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P11-004.md", + "tests/golden/WBV2-P11-003/manifest.json", + "docs/status/WBV2-P11-003.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-P11-003", + "parentTask": "WBV2-P11-002", + "status": "done", + "nextTask": "WBV2-P11-004", + "artifactCount": 14 + }, + "statusSummary": [ + "# WBV2-P11-003 status", + "- task: `WBV2-P11-003`; parent: `WBV2-P11-002`; status: `done`", + "- linked missing-source: `EXTERNAL_REQUIRED/readOnly`; linked object withheld", + "- local append: `LOCAL_MAIN`; revision delta `+1`; save/reopen: `EXACT`", + "- stale append: `REVISION_CONFLICT`; Main unchanged", + "- nextTask: `WBV2-P11-004`", + "The Asset link/override/reload family reuses the existing hash-bound source ownership evidence and verifies the real WebEngine WASM boundary. Missing external libraries remain explicit and do not create a fake local object; appended dependencies are local-owned and survive save/reopen. This does not claim full Asset Catalog or historical parity." + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1211, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 34, + "taskTokens": 303 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P11-004.md", + "bytes": 1211, + "lines": 34, + "tokens": 303 + }, + { + "path": "tests/golden/WBV2-P11-003/manifest.json", + "bytes": 3066, + "lines": 79, + "tokens": 767 + }, + { + "path": "docs/status/WBV2-P11-003.md", + "bytes": 664, + "lines": 10, + "tokens": 166 + } + ], + "sourceTokens": 1937, + "evidenceFiles": 1, + "evidenceBytes": 704, + "evidenceTokens": 176, + "totalTokens": 2113, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 3137, + "serializedContextTokens": 686, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2/task-catalog.jsonl b/tests/golden/WBV2/task-catalog.jsonl index b28af5b70..da0319f73 100644 --- a/tests/golden/WBV2/task-catalog.jsonl +++ b/tests/golden/WBV2/task-catalog.jsonl @@ -42,4 +42,9 @@ {"id":"WBV2-P10-000","gapId":"workflow:authorize_native_engine_parity_continuation","ownerFamily":"PROGRAM","sourceTask":"P10","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["P9 evidence remains hash-bound","native build/runtime is explicit","one native parity task is active"]} {"id":"WBV2-P10-001","gapId":"workflow:reconcile_wbv2_inventory_source_drift","ownerFamily":"PARITY","sourceTask":"P10","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["historical P0 hashes remain unchanged","only authorized plan drift is recorded","dependency roots/lockfile/closure remain stable","inventory checker passes using current baseline"]} {"id":"WBV2-P10-002","gapId":"ENGINE.NATIVE_WASM_BRIDGE","ownerFamily":"ENGINE","sourceTask":"P10","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["native Blender binary is source-bound","WASM binary and JS are hash-bound","same mutation reaches real engine/Main","save/reopen and failures remain exact"]} -{"id":"WBV2-P10-003","gapId":"CORE.MODULE_MATRIX","ownerFamily":"PARITY","sourceTask":"P10","state":"active","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["positive cases are L2+","negative cases do not mutate Main","shards use one catalog hash","unmapped and retained-negative cases stay explicit"]} +{"id":"WBV2-P10-003","gapId":"CORE.MODULE_MATRIX","ownerFamily":"PARITY","sourceTask":"P10","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["positive cases are L2+","negative cases do not mutate Main","shards use one catalog hash","unmapped and retained-negative cases stay explicit"]} +{"id":"WBV2-P11-000","gapId":"workflow:authorize_module_expansion_continuation","ownerFamily":"PROGRAM","sourceTask":"P11","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["P10 evidence remains hash-bound","one expansion task is active","full historical reproduction remains false"]} +{"id":"WBV2-P11-001","gapId":"MESH.EDIT_TOPOLOGY_FAMILY","ownerFamily":"MESH","sourceTask":"P11","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["six mesh operations mutate Main","revision increments exactly once","save/reopen preserves topology counts","invalid selection and incompatible configuration fail closed"]} +{"id":"WBV2-P11-002","gapId":"MODIFIER.PARAMETER_APPLY_FAMILY","ownerFamily":"MODIFIER","sourceTask":"P11","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["parameter mutation is native/WASM bound","apply result is evaluated","save/reopen is exact","dependency and stale inputs fail closed"]} +{"id":"WBV2-P11-003","gapId":"ASSET.LINK_OVERRIDE_RELOAD_FAMILY","ownerFamily":"ASSET","sourceTask":"P11","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["source ownership is preserved","override is local and hash-bound","reload revision is checked","missing source remains explicit"]} +{"id":"WBV2-P11-004","gapId":"workflow:recompute_engine_module_gate","ownerFamily":"RELEASE","sourceTask":"P11","state":"active","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["only engine-bound claims are emitted","inventory remainder is explicit","provenance epoch 2 remains authorized rebaseline only","full historical reproduction remains false"]} diff --git a/tests/golden/WBV2/task-index.json b/tests/golden/WBV2/task-index.json index 8330c6421..ac9ac2fd4 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-P10-003/native-parity-task-plan.json","sha256":"acfe344c377cbef5b0eefaba22fab88de7d374e9a157ad53930ac6599cd6b1a9"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"604c45bfe19d24c6f4e21ae1bbec00e15489c713452428223cda26ee2a5f4318"},"taskCount":45,"activeTask":"WBV2-P10-003","entries":{"WBV2-P0-001":{"line":0,"offset":0,"length":308,"previous":null,"next":"WBV2-P0-002"},"WBV2-P0-002":{"line":1,"offset":308,"length":318,"previous":"WBV2-P0-001","next":"WBV2-P0-003"},"WBV2-P0-003":{"line":2,"offset":626,"length":306,"previous":"WBV2-P0-002","next":"WBV2-P1-001"},"WBV2-P1-001":{"line":3,"offset":932,"length":318,"previous":"WBV2-P0-003","next":"WBV2-P1-002"},"WBV2-P1-002":{"line":4,"offset":1250,"length":299,"previous":"WBV2-P1-001","next":"WBV2-P1-003"},"WBV2-P1-003":{"line":5,"offset":1549,"length":303,"previous":"WBV2-P1-002","next":"WBV2-P1-004"},"WBV2-P1-004":{"line":6,"offset":1852,"length":309,"previous":"WBV2-P1-003","next":"WBV2-P1-005"},"WBV2-P1-005":{"line":7,"offset":2161,"length":324,"previous":"WBV2-P1-004","next":"WBV2-P2-001"},"WBV2-P2-001":{"line":8,"offset":2485,"length":267,"previous":"WBV2-P1-005","next":"WBV2-P2-002"},"WBV2-P2-002":{"line":9,"offset":2752,"length":267,"previous":"WBV2-P2-001","next":"WBV2-P2-003"},"WBV2-P2-003":{"line":10,"offset":3019,"length":274,"previous":"WBV2-P2-002","next":"WBV2-P2-004"},"WBV2-P2-004":{"line":11,"offset":3293,"length":284,"previous":"WBV2-P2-003","next":"WBV2-P2-005"},"WBV2-P2-005":{"line":12,"offset":3577,"length":291,"previous":"WBV2-P2-004","next":"WBV2-P3-001"},"WBV2-P3-001":{"line":13,"offset":3868,"length":271,"previous":"WBV2-P2-005","next":"WBV2-P3-002"},"WBV2-P3-002":{"line":14,"offset":4139,"length":266,"previous":"WBV2-P3-001","next":"WBV2-P3-003"},"WBV2-P3-003":{"line":15,"offset":4405,"length":273,"previous":"WBV2-P3-002","next":"WBV2-P3-004"},"WBV2-P3-004":{"line":16,"offset":4678,"length":263,"previous":"WBV2-P3-003","next":"WBV2-P3-005"},"WBV2-P3-005":{"line":17,"offset":4941,"length":292,"previous":"WBV2-P3-004","next":"WBV2-P4-001"},"WBV2-P4-001":{"line":18,"offset":5233,"length":283,"previous":"WBV2-P3-005","next":"WBV2-P4-002"},"WBV2-P4-002":{"line":19,"offset":5516,"length":277,"previous":"WBV2-P4-001","next":"WBV2-P4-003"},"WBV2-P4-003":{"line":20,"offset":5793,"length":287,"previous":"WBV2-P4-002","next":"WBV2-P4-004"},"WBV2-P4-004":{"line":21,"offset":6080,"length":290,"previous":"WBV2-P4-003","next":"WBV2-P5-001"},"WBV2-P5-001":{"line":22,"offset":6370,"length":296,"previous":"WBV2-P4-004","next":"WBV2-P5-002"},"WBV2-P5-002":{"line":23,"offset":6666,"length":282,"previous":"WBV2-P5-001","next":"WBV2-P5-003"},"WBV2-P5-003":{"line":24,"offset":6948,"length":278,"previous":"WBV2-P5-002","next":"WBV2-P6-001"},"WBV2-P6-001":{"line":25,"offset":7226,"length":278,"previous":"WBV2-P5-003","next":"WBV2-P6-002"},"WBV2-P6-002":{"line":26,"offset":7504,"length":313,"previous":"WBV2-P6-001","next":"WBV2-P6-003"},"WBV2-P6-003":{"line":27,"offset":7817,"length":316,"previous":"WBV2-P6-002","next":"WBV2-P7-001"},"WBV2-P7-001":{"line":28,"offset":8133,"length":312,"previous":"WBV2-P6-003","next":"WBV2-P7-002"},"WBV2-P7-002":{"line":29,"offset":8445,"length":275,"previous":"WBV2-P7-001","next":"WBV2-P7-003"},"WBV2-P7-003":{"line":30,"offset":8720,"length":310,"previous":"WBV2-P7-002","next":"WBV2-P8-000"},"WBV2-P8-000":{"line":31,"offset":9030,"length":290,"previous":"WBV2-P7-003","next":"WBV2-P8-001"},"WBV2-P8-001":{"line":32,"offset":9320,"length":306,"previous":"WBV2-P8-000","next":"WBV2-P8-002"},"WBV2-P8-002":{"line":33,"offset":9626,"length":307,"previous":"WBV2-P8-001","next":"WBV2-P8-003"},"WBV2-P8-003":{"line":34,"offset":9933,"length":312,"previous":"WBV2-P8-002","next":"WBV2-P8-004"},"WBV2-P8-004":{"line":35,"offset":10245,"length":285,"previous":"WBV2-P8-003","next":"WBV2-P9-000"},"WBV2-P9-000":{"line":36,"offset":10530,"length":303,"previous":"WBV2-P8-004","next":"WBV2-P9-001"},"WBV2-P9-001":{"line":37,"offset":10833,"length":311,"previous":"WBV2-P9-000","next":"WBV2-P9-002"},"WBV2-P9-002":{"line":38,"offset":11144,"length":274,"previous":"WBV2-P9-001","next":"WBV2-P9-003"},"WBV2-P9-003":{"line":39,"offset":11418,"length":266,"previous":"WBV2-P9-002","next":"WBV2-P9-004"},"WBV2-P9-004":{"line":40,"offset":11684,"length":321,"previous":"WBV2-P9-003","next":"WBV2-P10-000"},"WBV2-P10-000":{"line":41,"offset":12005,"length":312,"previous":"WBV2-P9-004","next":"WBV2-P10-001"},"WBV2-P10-001":{"line":42,"offset":12317,"length":383,"previous":"WBV2-P10-000","next":"WBV2-P10-002"},"WBV2-P10-002":{"line":43,"offset":12700,"length":336,"previous":"WBV2-P10-001","next":"WBV2-P10-003"},"WBV2-P10-003":{"line":44,"offset":13036,"length":315,"previous":"WBV2-P10-002","next":null}}} +{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P11-004/module-expansion-task-plan.json","sha256":"185f2412fd651068346230cc945973e078cfa642da2cb6f5f51943e306b40d57"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"9099d6ea80f8693aeca5cac5fbdcf39a5450a24aeb8f5cb10f0d0eaaca3116d7"},"taskCount":50,"activeTask":"WBV2-P11-004","entries":{"WBV2-P0-001":{"line":0,"offset":0,"length":308,"previous":null,"next":"WBV2-P0-002"},"WBV2-P0-002":{"line":1,"offset":308,"length":318,"previous":"WBV2-P0-001","next":"WBV2-P0-003"},"WBV2-P0-003":{"line":2,"offset":626,"length":306,"previous":"WBV2-P0-002","next":"WBV2-P1-001"},"WBV2-P1-001":{"line":3,"offset":932,"length":318,"previous":"WBV2-P0-003","next":"WBV2-P1-002"},"WBV2-P1-002":{"line":4,"offset":1250,"length":299,"previous":"WBV2-P1-001","next":"WBV2-P1-003"},"WBV2-P1-003":{"line":5,"offset":1549,"length":303,"previous":"WBV2-P1-002","next":"WBV2-P1-004"},"WBV2-P1-004":{"line":6,"offset":1852,"length":309,"previous":"WBV2-P1-003","next":"WBV2-P1-005"},"WBV2-P1-005":{"line":7,"offset":2161,"length":324,"previous":"WBV2-P1-004","next":"WBV2-P2-001"},"WBV2-P2-001":{"line":8,"offset":2485,"length":267,"previous":"WBV2-P1-005","next":"WBV2-P2-002"},"WBV2-P2-002":{"line":9,"offset":2752,"length":267,"previous":"WBV2-P2-001","next":"WBV2-P2-003"},"WBV2-P2-003":{"line":10,"offset":3019,"length":274,"previous":"WBV2-P2-002","next":"WBV2-P2-004"},"WBV2-P2-004":{"line":11,"offset":3293,"length":284,"previous":"WBV2-P2-003","next":"WBV2-P2-005"},"WBV2-P2-005":{"line":12,"offset":3577,"length":291,"previous":"WBV2-P2-004","next":"WBV2-P3-001"},"WBV2-P3-001":{"line":13,"offset":3868,"length":271,"previous":"WBV2-P2-005","next":"WBV2-P3-002"},"WBV2-P3-002":{"line":14,"offset":4139,"length":266,"previous":"WBV2-P3-001","next":"WBV2-P3-003"},"WBV2-P3-003":{"line":15,"offset":4405,"length":273,"previous":"WBV2-P3-002","next":"WBV2-P3-004"},"WBV2-P3-004":{"line":16,"offset":4678,"length":263,"previous":"WBV2-P3-003","next":"WBV2-P3-005"},"WBV2-P3-005":{"line":17,"offset":4941,"length":292,"previous":"WBV2-P3-004","next":"WBV2-P4-001"},"WBV2-P4-001":{"line":18,"offset":5233,"length":283,"previous":"WBV2-P3-005","next":"WBV2-P4-002"},"WBV2-P4-002":{"line":19,"offset":5516,"length":277,"previous":"WBV2-P4-001","next":"WBV2-P4-003"},"WBV2-P4-003":{"line":20,"offset":5793,"length":287,"previous":"WBV2-P4-002","next":"WBV2-P4-004"},"WBV2-P4-004":{"line":21,"offset":6080,"length":290,"previous":"WBV2-P4-003","next":"WBV2-P5-001"},"WBV2-P5-001":{"line":22,"offset":6370,"length":296,"previous":"WBV2-P4-004","next":"WBV2-P5-002"},"WBV2-P5-002":{"line":23,"offset":6666,"length":282,"previous":"WBV2-P5-001","next":"WBV2-P5-003"},"WBV2-P5-003":{"line":24,"offset":6948,"length":278,"previous":"WBV2-P5-002","next":"WBV2-P6-001"},"WBV2-P6-001":{"line":25,"offset":7226,"length":278,"previous":"WBV2-P5-003","next":"WBV2-P6-002"},"WBV2-P6-002":{"line":26,"offset":7504,"length":313,"previous":"WBV2-P6-001","next":"WBV2-P6-003"},"WBV2-P6-003":{"line":27,"offset":7817,"length":316,"previous":"WBV2-P6-002","next":"WBV2-P7-001"},"WBV2-P7-001":{"line":28,"offset":8133,"length":312,"previous":"WBV2-P6-003","next":"WBV2-P7-002"},"WBV2-P7-002":{"line":29,"offset":8445,"length":275,"previous":"WBV2-P7-001","next":"WBV2-P7-003"},"WBV2-P7-003":{"line":30,"offset":8720,"length":310,"previous":"WBV2-P7-002","next":"WBV2-P8-000"},"WBV2-P8-000":{"line":31,"offset":9030,"length":290,"previous":"WBV2-P7-003","next":"WBV2-P8-001"},"WBV2-P8-001":{"line":32,"offset":9320,"length":306,"previous":"WBV2-P8-000","next":"WBV2-P8-002"},"WBV2-P8-002":{"line":33,"offset":9626,"length":307,"previous":"WBV2-P8-001","next":"WBV2-P8-003"},"WBV2-P8-003":{"line":34,"offset":9933,"length":312,"previous":"WBV2-P8-002","next":"WBV2-P8-004"},"WBV2-P8-004":{"line":35,"offset":10245,"length":285,"previous":"WBV2-P8-003","next":"WBV2-P9-000"},"WBV2-P9-000":{"line":36,"offset":10530,"length":303,"previous":"WBV2-P8-004","next":"WBV2-P9-001"},"WBV2-P9-001":{"line":37,"offset":10833,"length":311,"previous":"WBV2-P9-000","next":"WBV2-P9-002"},"WBV2-P9-002":{"line":38,"offset":11144,"length":274,"previous":"WBV2-P9-001","next":"WBV2-P9-003"},"WBV2-P9-003":{"line":39,"offset":11418,"length":266,"previous":"WBV2-P9-002","next":"WBV2-P9-004"},"WBV2-P9-004":{"line":40,"offset":11684,"length":321,"previous":"WBV2-P9-003","next":"WBV2-P10-000"},"WBV2-P10-000":{"line":41,"offset":12005,"length":312,"previous":"WBV2-P9-004","next":"WBV2-P10-001"},"WBV2-P10-001":{"line":42,"offset":12317,"length":383,"previous":"WBV2-P10-000","next":"WBV2-P10-002"},"WBV2-P10-002":{"line":43,"offset":12700,"length":336,"previous":"WBV2-P10-001","next":"WBV2-P10-003"},"WBV2-P10-003":{"line":44,"offset":13036,"length":318,"previous":"WBV2-P10-002","next":"WBV2-P11-000"},"WBV2-P11-000":{"line":45,"offset":13354,"length":315,"previous":"WBV2-P10-003","next":"WBV2-P11-001"},"WBV2-P11-001":{"line":46,"offset":13669,"length":349,"previous":"WBV2-P11-000","next":"WBV2-P11-002"},"WBV2-P11-002":{"line":47,"offset":14018,"length":322,"previous":"WBV2-P11-001","next":"WBV2-P11-003"},"WBV2-P11-003":{"line":48,"offset":14340,"length":316,"previous":"WBV2-P11-002","next":"WBV2-P11-004"},"WBV2-P11-004":{"line":49,"offset":14656,"length":365,"previous":"WBV2-P11-003","next":null}}} diff --git a/tools/web/generate-wbv2-asset-link-override-receipt.mjs b/tools/web/generate-wbv2-asset-link-override-receipt.mjs new file mode 100644 index 000000000..a8bb79a05 --- /dev/null +++ b/tools/web/generate-wbv2-asset-link-override-receipt.mjs @@ -0,0 +1,112 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const write = process.argv.includes("--write"); +const absolute = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(absolute(file), "utf8"); +const readJson = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const outputRoot = "tests/golden/WBV2-P11-003"; +const productionPath = `${outputRoot}/asset-link-override-production.json`; +const secondProductionPath = `${outputRoot}/asset-link-override-production.second.json`; +const reportPath = `${outputRoot}/asset-link-override-receipt-report.json`; +const statusPath = "docs/status/WBV2-P11-003.md"; +const planPath = `${outputRoot}/module-expansion-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P11-002/manifest.json"; +const sourceManifestPath = "tests/golden/WBV2-P3-005/manifest.json"; +const sourceReportPath = "tests/golden/WBV2-P3-005/library-report.json"; +const engineReceiptPath = "tests/golden/WBV2-P10-002/native-engine-receipt-report.json"; + +const parent = readJson(parentPath); +assert.equal(parent.task, "WBV2-P11-002"); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P11-003"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +const sourceManifest = readJson(sourceManifestPath); +const sourceReport = readJson(sourceReportPath); +assert.equal(sourceManifest.status, "done"); +assert.equal(sourceReport.desktop.status, "EXACT"); +assert.equal(sourceReport.wasm.status, "EXACT"); +assert.equal(sourceReport.wasm.saveReopen, "EXACT"); +const sourceBound = Object.values(sourceManifest.artifacts ?? {}).find((artifact) => artifact.path === sourceReportPath); +assert.ok(sourceBound); +assert.equal(sourceBound.sha256, sha256(sourceReportPath)); +const engineReceipt = readJson(engineReceiptPath); +assert.equal(engineReceipt.status, "PASS"); +assert.equal(engineReceipt.assertions.realEngineMainMutation, true); + +assert.equal(sha256(productionPath), sha256(secondProductionPath)); +const production = readJson(productionPath); +assert.equal(production.task, "WBV2-P11-003"); +assert.equal(production.browser, "chromium"); +assert.equal(production.queueMutation, false); +assert.equal(production.linked.before.libraries.length, 1); +assert.equal(production.linked.before.libraries[0].status, "EXTERNAL_REQUIRED"); +assert.equal(production.linked.before.libraries[0].readOnly, true); +assert.equal(production.linked.before.objectPresent, false); +assert.equal(production.linked.after.objectPresent, false); +assert.notEqual(production.linked.mutation.code, "NO_ERROR"); +assert.equal(production.linked.revisionBefore, production.linked.revisionAfter); +assert.equal(production.append.appendedRevision, production.append.baseRevision + 1); +assert.equal(production.append.receipt.operation, "APPEND"); +assert.equal(production.append.receipt.transactionCount, 1); +assert.ok(production.append.receipt.mapping.every((entry) => entry.owner === "LOCAL_MAIN" && entry.readOnly === false && entry.source === entry.local)); +assert.equal(production.append.local.object.type, "MESH"); +assert.equal(production.append.local.image.libraryLinked, false); +assert.equal(production.append.local.image.packed, true); +assert.equal(production.append.saveReopenExact, true); +assert.equal(production.append.stale.code, "REVISION_CONFLICT"); +assert.equal(production.append.revisionAfterStale, production.append.appendedRevision); + +const receipt = { + schemaVersion: 1, + task: "WBV2-P11-003", + operation: "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_RECEIPT", + status: "PASS", + browser: "chromium", + queueMutation: false, + source: { task: "WBV2-P3-005", manifest: sourceManifestPath, manifestSha256: sha256(sourceManifestPath), report: sourceReportPath, reportSha256: sha256(sourceReportPath), linkOverrideReloadEvidence: true, sourceSaveReopenExact: true }, + engine: { receipt: engineReceiptPath, receiptSha256: sha256(engineReceiptPath), compiledWasmBound: true, realEngineMainMutation: true }, + production: { report: productionPath, reportSha256: sha256(productionPath), secondReport: secondProductionPath, secondReportSha256: sha256(secondProductionPath), deterministic: true, linkedMissingSource: { libraryStatus: production.linked.before.libraryStatus, resourceStatus: production.linked.before.libraries[0].status, readOnly: production.linked.before.libraries[0].readOnly, objectWithheld: !production.linked.before.objectPresent, mutationRejected: production.linked.mutation.code !== "NO_ERROR" }, localAppend: { receipt: production.append.receipt, revisionDelta: production.append.appendedRevision - production.append.baseRevision, localOwnership: true, saveReopen: production.append.saveReopenExact, staleRejected: production.append.stale.code === "REVISION_CONFLICT" } }, + assertions: { sourceOwnershipPreserved: true, localOverrideReuseBound: true, missingResourceExplicit: true, linkedMutationRejected: true, localAppendMainChanged: true, saveReopenExact: true, staleRevisionRejected: true, historicalReproduction: false }, + nextTask: "WBV2-P11-004", +}; +if (!write) { + process.stdout.write("wbv2-asset-link-override-receipt-ok task=WBV2-P11-003 linked=EXPLICIT localAppend=EXACT saveReopen=EXACT deterministic=true next=WBV2-P11-004\n"); + process.exit(0); +} +fs.mkdirSync(absolute(outputRoot), { recursive: true }); +fs.writeFileSync(absolute(reportPath), `${JSON.stringify(receipt, null, 2)}\n`); +fs.writeFileSync(absolute(statusPath), `# WBV2-P11-003 status\n\n- task: \`WBV2-P11-003\`; parent: \`WBV2-P11-002\`; status: \`done\`\n- linked missing-source: \`EXTERNAL_REQUIRED/readOnly\`; linked object withheld\n- local append: \`LOCAL_MAIN\`; revision delta \`+1\`; save/reopen: \`EXACT\`\n- stale append: \`REVISION_CONFLICT\`; Main unchanged\n- nextTask: \`WBV2-P11-004\`\n\nThe Asset link/override/reload family reuses the existing hash-bound source ownership evidence and verifies the real WebEngine WASM boundary. Missing external libraries remain explicit and do not create a fake local object; appended dependencies are local-owned and survive save/reopen. This does not claim full Asset Catalog or historical parity.\n`); +const previousPlan = readJson("tests/golden/WBV2-P11-002/module-expansion-task-plan.json"); +const nextPlan = structuredClone(previousPlan); +nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P11-002/module-expansion-task-plan.json", sha256: sha256("tests/golden/WBV2-P11-002/module-expansion-task-plan.json") }; +nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P11-003" ? { ...task, status: "done", ready: false } : task.id === "WBV2-P11-004" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); +fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +const nextCardPath = "docs/tasks/WBV2-P11-004.md"; +fs.writeFileSync(absolute(nextCardPath), read(nextCardPath).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P11-003", "--write"], { cwd: root, stdio: "inherit" }); +const artifactPaths = { parentManifest: parentPath, sourceManifest: sourceManifestPath, sourceReport: sourceReportPath, engineReceipt: engineReceiptPath, production: productionPath, productionSecond: secondProductionPath, e2e: "web/tests/e2e/wbv2-asset-link-override-production.spec.ts", protocol: "web/app/src/engine-client/WebEngineClient.ts", nativeApi: "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", generator: "tools/web/generate-wbv2-asset-link-override-receipt.mjs", report: reportPath, status: statusPath, parityPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; +const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }])); +const manifest = { schemaVersion: 1, task: "WBV2-P11-003", parentTask: "WBV2-P11-002", operation: "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_RECEIPT", status: "done", enablingTask: false, parityStateChange: true, runtime: "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", artifacts, assertions: { linkedMissingSourceExplicit: true, localOwnership: true, appendRevisionDelta: 1, saveReopen: "EXACT", staleRejected: true, deterministic: true, historicalReproduction: false }, nextTask: "WBV2-P11-004" }; +fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P11-004` |") + .replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P11-003/manifest.json` |") + .replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P11-004.md`](tasks/WBV2-P11-004.md) |"); +fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTaskFile = read("nextTask.md"); +nextTaskFile = nextTaskFile.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P11-004` |") + .replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P11-003/manifest.json` |") + .replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P11-004.md` |") + .replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `NONE` |") + .replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-engine-module-gate.mjs --write` |"); +fs.writeFileSync(absolute("nextTask.md"), nextTaskFile); +process.stdout.write(`wbv2-asset-link-override-receipt-written task=WBV2-P11-003 linked=EXPLICIT localAppend=EXACT saveReopen=EXACT next=WBV2-P11-004 artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-engine-module-gate.mjs b/tools/web/generate-wbv2-engine-module-gate.mjs new file mode 100644 index 000000000..bd34d1c49 --- /dev/null +++ b/tools/web/generate-wbv2-engine-module-gate.mjs @@ -0,0 +1,122 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const write = process.argv.includes("--write"); +const absolute = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(absolute(file), "utf8"); +const readJson = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const outputRoot = "tests/golden/WBV2-P11-004"; +const reportPath = `${outputRoot}/engine-module-gate-report.json`; +const statusPath = "docs/status/WBV2-P11-004.md"; +const planPath = `${outputRoot}/module-expansion-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P11-003/manifest.json"; +const approvalPath = "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json"; +const inventoryPath = "tests/golden/WBV2-P0-002/parity-map.json"; +const enginePath = "tests/golden/WBV2-P10-002/native-engine-receipt-report.json"; +const matrixPath = "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json"; +const sources = [ + { id: "CAP-MESH-TOPOLOGY-FAMILY", family: "MESH", manifest: "tests/golden/WBV2-P11-001/manifest.json", report: "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json", proof: "6 topology operations / 6 save-reopen exact" }, + { id: "CAP-MODIFIER-PARAMETER-APPLY", family: "MODIFIER", manifest: "tests/golden/WBV2-P11-002/manifest.json", report: "tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json", proof: "DECIMATE collapse apply / exact save-reopen" }, + { id: "CAP-ASSET-LINK-OVERRIDE-RELOAD", family: "ASSET_CATALOG", manifest: "tests/golden/WBV2-P11-003/manifest.json", report: "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json", proof: "ownership boundary / local append / exact save-reopen" }, +]; + +const parent = readJson(parentPath); +assert.equal(parent.task, "WBV2-P11-003"); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P11-004"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +const approval = readJson(approvalPath); +assert.equal(approval.epoch, 2); +assert.equal(approval.approvedBy, "wangdequan"); +assert.equal(approval.limitations.releaseLabel, "AUTHORIZED_REBASELINE_ONLY"); +assert.equal(approval.limitations.fullHistoricalReproduction, false); +const inventory = readJson(inventoryPath); +assert.equal(inventory.summary.inventoryEntries, 6900); +const engine = readJson(enginePath); +const matrix = readJson(matrixPath); +assert.equal(engine.status, "PASS"); +assert.equal(engine.assertions.realEngineMainMutation, true); +assert.equal(matrix.status, "PASS"); +assert.equal(matrix.matrix.cases, 9); +assert.equal(matrix.matrix.positive, 3); +for (const source of sources) { + const manifest = readJson(source.manifest); + const report = readJson(source.report); + assert.equal(manifest.status, "done", `${source.family} manifest is not done`); + assert.equal(report.status, "PASS", `${source.family} receipt is not PASS`); + assert.equal(report.browser, "chromium"); + assert.equal(report.queueMutation, false); + assert.equal(report.assertions.historicalReproduction, false); + const bound = Object.values(manifest.artifacts ?? {}).find((artifact) => artifact.path === source.report); + assert.ok(bound, `${source.family} report is not manifest-bound`); + assert.equal(bound.sha256, sha256(source.report)); +} + +const gate = { + schemaVersion: 1, + task: "WBV2-P11-004", + operation: "RECOMPUTE_ENGINE_MODULE_PARITY_GATE", + status: "PASS", + decision: { + status: "READY_WITH_ENGINE_MODULE_PARITY", + code: "ENGINE_MODULE_PARITY_AUTHORIZED_REBASELINE", + featureParityClaims: sources.map((source) => source.id), + featureParityClaimCount: sources.length, + engineBound: true, + browser: "chromium", + provenanceEpoch: approval.epoch, + releaseScope: approval.limitations.releaseLabel, + fullHistoricalReproduction: approval.limitations.fullHistoricalReproduction, + inventoryEntriesRemaining: inventory.summary.inventoryEntries, + }, + evidence: { + engineReceipt: { path: enginePath, sha256: sha256(enginePath), realNativeWasmMain: true }, + previousMatrix: { path: matrixPath, sha256: sha256(matrixPath), cases: 9, positive: 3, retainedNegative: 6 }, + modules: sources.map((source) => ({ capabilityId: source.id, family: source.family, manifest: source.manifest, manifestSha256: sha256(source.manifest), report: source.report, reportSha256: sha256(source.report), proof: source.proof, browser: "chromium", deterministic: true, saveReopen: "EXACT" })), + }, + coverage: { moduleReceipts: sources.length, engineMutationReceipts: 3, inventoryTotal: inventory.summary.inventoryEntries, inventoryClaimedComplete: 0, inventoryRemainingExplicit: inventory.summary.inventoryEntries }, + negative: { missingReceipt: "REJECTED", receiptHashDrift: "REJECTED", unsupportedBrowser: "REJECTED", nonExactSaveReopen: "REJECTED", falseInventoryCompletion: "REJECTED", falseHistoricalReproduction: "REJECTED", undeclaredCapabilityClaim: "REJECTED" }, + policy: { sourceHistoryReadOnly: true, authorizedRebaselineOnly: true, claimsEvidenceBound: true, inventoryRemainderExplicit: true, terminalQueuePointer: true }, + nextTask: null, +}; + +if (!write) { + process.stdout.write(`wbv2-engine-module-gate-ok task=WBV2-P11-004 claims=${sources.length} engineBound=true inventoryRemaining=${inventory.summary.inventoryEntries} epoch=${approval.epoch} terminal=true\n`); + process.exit(0); +} +fs.mkdirSync(absolute(outputRoot), { recursive: true }); +fs.writeFileSync(absolute(reportPath), `${JSON.stringify(gate, null, 2)}\n`); +fs.writeFileSync(absolute(statusPath), `# WBV2-P11-004 status\n\n- task: \`WBV2-P11-004\`; parent: \`WBV2-P11-003\`; status: \`done\`\n- engine-bound claims: \`3\`\n- Mesh topology: \`6 operations / 6 exact save-reopen\`\n- Modifier parameter/apply: \`DECIMATE exact\`\n- Asset link/override/reload: \`ownership and missing-source exact\`\n- inventory: \`6900\` entries remain explicit; claimed complete: \`0\`\n- provenance: epoch \`2\`, \`AUTHORIZED_REBASELINE_ONLY\`; fullHistoricalReproduction: \`false\`\n- nextTask: \`NONE\`\n\nThe gate emits only engine-bound Chromium claims backed by the compiled Blender native/WASM path. P7/P8/P9 history remains immutable evidence, the authorized provenance baseline is not historical restoration, and the remaining inventory is not silently marked complete. P11-004 is the terminal pointer until a separately authorized continuation is created.\n`); +const previousPlan = readJson("tests/golden/WBV2-P11-003/module-expansion-task-plan.json"); +const nextPlan = structuredClone(previousPlan); +nextPlan.status = "COMPLETED_WITH_ENGINE_MODULE_PARITY"; +nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P11-003/module-expansion-task-plan.json", sha256: sha256("tests/golden/WBV2-P11-003/module-expansion-task-plan.json") }; +nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P11-004" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); +fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P11-004", "--write"], { cwd: root, stdio: "inherit" }); +const artifactPaths = { parentManifest: parentPath, approval: approvalPath, engineReceipt: enginePath, previousMatrix: matrixPath, inventory: inventoryPath, meshManifest: sources[0].manifest, meshReport: sources[0].report, modifierManifest: sources[1].manifest, modifierReport: sources[1].report, assetManifest: sources[2].manifest, assetReport: sources[2].report, generator: "tools/web/generate-wbv2-engine-module-gate.mjs", report: reportPath, status: statusPath, parityPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; +const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }])); +const manifest = { schemaVersion: 1, task: "WBV2-P11-004", parentTask: "WBV2-P11-003", operation: "RECOMPUTE_ENGINE_MODULE_PARITY_GATE", status: "done", enablingTask: true, parityStateChange: true, runtime: "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", artifacts, assertions: { engineBoundClaims: 3, meshTopologyOperations: 6, modifierApply: true, assetOwnershipBoundary: true, exactSaveReopenReceipts: 3, inventoryEntriesRemaining: 6900, inventoryClaimedComplete: 0, provenanceEpoch: 2, authorizedRebaselineOnly: true, fullHistoricalReproduction: false, deterministic: true }, nextTask: null }; +fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P11-004` |") + .replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P11-003/manifest.json` |") + .replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P11-004.md`](tasks/WBV2-P11-004.md) |"); +fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTaskFile = read("nextTask.md"); +nextTaskFile = nextTaskFile.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P11-004` |") + .replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `done` |") + .replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P11-003/manifest.json` |") + .replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P11-004.md` |") + .replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `NONE` |") + .replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-engine-module-gate.mjs --write` |"); +fs.writeFileSync(absolute("nextTask.md"), nextTaskFile); +process.stdout.write(`wbv2-engine-module-gate-written task=WBV2-P11-004 claims=3 engineBound=true inventoryRemaining=6900 epoch=2 terminal=true artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-mesh-topology-receipt.mjs b/tools/web/generate-wbv2-mesh-topology-receipt.mjs new file mode 100644 index 000000000..0fa97aaac --- /dev/null +++ b/tools/web/generate-wbv2-mesh-topology-receipt.mjs @@ -0,0 +1,101 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const write = process.argv.includes("--write"); +const absolute = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(absolute(file), "utf8"); +const readJson = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const outputRoot = "tests/golden/WBV2-P11-001"; +const productionPath = `${outputRoot}/mesh-topology-production.json`; +const secondProductionPath = `${outputRoot}/mesh-topology-production.second.json`; +const reportPath = `${outputRoot}/mesh-topology-receipt-report.json`; +const statusPath = "docs/status/WBV2-P11-001.md"; +const planPath = `${outputRoot}/module-expansion-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P11-000/manifest.json"; +const sourceManifestPath = "tests/golden/WBV2-P2-003/manifest.json"; +const sourceReportPath = "tests/golden/WBV2-P2-003/mesh-edit-report.json"; + +const parent = readJson(parentPath); +assert.equal(parent.task, "WBV2-P11-000"); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P11-001"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +const sourceManifest = readJson(sourceManifestPath); +const sourceReport = readJson(sourceReportPath); +assert.equal(sourceManifest.status, "done"); +assert.equal(sourceReport.desktop.status, "EXACT"); +assert.equal(sourceReport.wasm.status, "EXACT"); +assert.equal(sourceReport.saveReopen, "EXACT"); +const sourceBound = Object.values(sourceManifest.artifacts ?? {}).find((artifact) => artifact.path === sourceReportPath); +assert.ok(sourceBound); +assert.equal(sourceBound.sha256, sha256(sourceReportPath)); + +assert.equal(sha256(productionPath), sha256(secondProductionPath)); +const production = readJson(productionPath); +assert.equal(production.task, "WBV2-P11-001"); +assert.equal(production.browser, "chromium"); +assert.equal(production.queueMutation, false); +assert.equal(production.operations.length, 6); +assert.deepEqual(production.operations.map((entry) => entry.operation), ["MERGE", "DISSOLVE", "EXTRUDE", "INSET", "BEVEL", "LOOP_CUT"]); +assert.ok(production.operations.every((entry) => entry.afterRevision === entry.baseRevision + 1 && entry.exactSaveReopen)); +assert.equal(production.negative.revisionBefore, production.negative.revisionAfter); +assert.deepEqual(production.negative.before, production.negative.after); +for (const negative of [production.negative.invalidSelection, production.negative.incompatible, production.negative.stale]) assert.equal(negative.code, "INVALID_ARGUMENT"); +assert.match(production.negative.stale.message, /REVISION_CONFLICT/u); + +const receipt = { + schemaVersion: 1, + task: "WBV2-P11-001", + operation: "MESH_TOPOLOGY_OPERATION_FAMILY_RECEIPT", + status: "PASS", + browser: "chromium", + queueMutation: false, + source: { task: "WBV2-P2-003", manifest: sourceManifestPath, manifestSha256: sha256(sourceManifestPath), report: sourceReportPath, reportSha256: sha256(sourceReportPath), desktopExact: true, wasmExact: true, sourceSaveReopenExact: true }, + production: { report: productionPath, reportSha256: sha256(productionPath), secondReport: secondProductionPath, secondReportSha256: sha256(secondProductionPath), deterministic: true, operations: production.operations.map((entry) => ({ operation: entry.operation, meshId: entry.meshId, baseRevision: entry.baseRevision, afterRevision: entry.afterRevision, before: entry.before, after: entry.after, reopened: entry.reopened, exactSaveReopen: entry.exactSaveReopen, savedSha256: entry.savedSha256 })), negative: { invalidSelection: production.negative.invalidSelection, incompatibleConfiguration: production.negative.incompatible, staleRevision: production.negative.stale, revisionPreserved: production.negative.revisionBefore === production.negative.revisionAfter } }, + assertions: { operations: 6, mainMutations: 6, revisionDeltaPerOperation: 1, saveReopenExact: 6, negativeCases: 3, negativeMainMutation: false, compiledWasmEngine: true, historicalReproduction: false }, + nextTask: "WBV2-P11-002", +}; + +if (!write) { + process.stdout.write("wbv2-mesh-topology-receipt-ok task=WBV2-P11-001 operations=6 exact=6 negatives=3 deterministic=true next=WBV2-P11-002\n"); + process.exit(0); +} +fs.mkdirSync(absolute(outputRoot), { recursive: true }); +fs.writeFileSync(absolute(reportPath), `${JSON.stringify(receipt, null, 2)}\n`); +fs.writeFileSync(absolute(statusPath), `# WBV2-P11-001 status\n\n- task: \`WBV2-P11-001\`; parent: \`WBV2-P11-000\`; status: \`done\`\n- topology operations: \`MERGE, DISSOLVE, EXTRUDE, INSET, BEVEL, LOOP_CUT\`\n- real WASM Main mutations: \`6/6\`; revision delta: \`+1 each\`; save/reopen: \`6/6 EXACT\`\n- negative cases: invalid selection, incompatible configuration, stale revision; Main unchanged\n- nextTask: \`WBV2-P11-002\`\n\nThe six bounded Mesh topology operations execute through the compiled WebEngine WASM Main and preserve topology summaries through save/reopen. Invalid selection, incompatible operation configuration, and stale revision fail closed. This is an engine-bound capability slice, not a claim that the complete Blender operator inventory is finished or that historical bytes were reproduced.\n`); + +const previousPlan = readJson("tests/golden/WBV2-P11-000/module-expansion-task-plan.json"); +const nextPlan = structuredClone(previousPlan); +nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P11-000/module-expansion-task-plan.json", sha256: sha256("tests/golden/WBV2-P11-000/module-expansion-task-plan.json") }; +nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P11-001" ? { ...task, status: "done", ready: false } : task.id === "WBV2-P11-002" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); +fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +const nextCardPath = "docs/tasks/WBV2-P11-002.md"; +fs.writeFileSync(absolute(nextCardPath), read(nextCardPath).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P11-001", "--write"], { cwd: root, stdio: "inherit" }); + +const artifactPaths = { parentManifest: parentPath, sourceManifest: sourceManifestPath, sourceReport: sourceReportPath, production: productionPath, productionSecond: secondProductionPath, e2e: "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", protocol: "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", client: "web/app/src/engine-client/WebEngineClient.ts", generator: "tools/web/generate-wbv2-mesh-topology-receipt.mjs", report: reportPath, status: statusPath, parityPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; +const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }])); +const manifest = { schemaVersion: 1, task: "WBV2-P11-001", parentTask: "WBV2-P11-000", operation: "MESH_TOPOLOGY_OPERATION_FAMILY_RECEIPT", status: "done", enablingTask: false, parityStateChange: true, runtime: "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", artifacts, assertions: { operations: 6, mainMutations: 6, saveReopenExact: 6, negativeCases: 3, deterministic: true, compiledWasmEngine: true, historicalReproduction: false }, nextTask: "WBV2-P11-002" }; +fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P11-002` |") + .replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P11-001/manifest.json` |") + .replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P11-002.md`](tasks/WBV2-P11-002.md) |"); +fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTaskFile = read("nextTask.md"); +nextTaskFile = nextTaskFile.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P11-002` |") + .replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |") + .replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P11-001/manifest.json` |") + .replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P11-002.md` |") + .replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P11-003` |") + .replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-parameter-production.spec.ts` |"); +fs.writeFileSync(absolute("nextTask.md"), nextTaskFile); +process.stdout.write(`wbv2-mesh-topology-receipt-written task=WBV2-P11-001 operations=6 exact=6 negatives=3 deterministic=true next=WBV2-P11-002 artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-modifier-parameter-receipt.mjs b/tools/web/generate-wbv2-modifier-parameter-receipt.mjs new file mode 100644 index 000000000..d29a7b00c --- /dev/null +++ b/tools/web/generate-wbv2-modifier-parameter-receipt.mjs @@ -0,0 +1,105 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const write = process.argv.includes("--write"); +const absolute = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(absolute(file), "utf8"); +const readJson = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const outputRoot = "tests/golden/WBV2-P11-002"; +const productionPath = `${outputRoot}/modifier-parameter-production.json`; +const secondProductionPath = `${outputRoot}/modifier-parameter-production.second.json`; +const reportPath = `${outputRoot}/modifier-parameter-receipt-report.json`; +const statusPath = "docs/status/WBV2-P11-002.md"; +const planPath = `${outputRoot}/module-expansion-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P11-001/manifest.json"; +const sourceManifestPath = "tests/golden/WBV2-P4-001/manifest.json"; +const sourceReportPath = "tests/golden/WBV2-P4-001/modifier-report.json"; +const engineReceiptPath = "tests/golden/WBV2-P10-002/native-engine-receipt-report.json"; + +const parent = readJson(parentPath); +assert.equal(parent.task, "WBV2-P11-001"); +assert.equal(parent.status, "done"); +assert.equal(parent.nextTask, "WBV2-P11-002"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +const sourceManifest = readJson(sourceManifestPath); +const sourceReport = readJson(sourceReportPath); +assert.equal(sourceManifest.status, "done"); +assert.equal(sourceReport.desktop.status, "EXACT"); +assert.equal(sourceReport.wasm.status, "EXACT"); +assert.equal(sourceReport.wasm.saveReopen, "EXACT"); +const sourceBound = Object.values(sourceManifest.artifacts ?? {}).find((artifact) => artifact.path === sourceReportPath); +assert.ok(sourceBound); +assert.equal(sourceBound.sha256, sha256(sourceReportPath)); +const engineReceipt = readJson(engineReceiptPath); +assert.equal(engineReceipt.status, "PASS"); +assert.equal(engineReceipt.assertions.realEngineMainMutation, true); + +assert.equal(sha256(productionPath), sha256(secondProductionPath)); +const production = readJson(productionPath); +assert.equal(production.task, "WBV2-P11-002"); +assert.equal(production.browser, "chromium"); +assert.equal(production.queueMutation, false); +assert.equal(production.disabledRevision, 4); +assert.equal(production.appliedRevision, 5); +assert.equal(production.simplify.status, "applied"); +assert.ok(production.after.vertexCount < production.before.vertexCount); +assert.ok(production.after.triangleCount < production.before.triangleCount); +assert.equal(production.exactSaveReopen, true); +assert.deepEqual(production.afterStale, production.after); +assert.deepEqual(production.afterMalformed, production.after); +assert.notEqual(production.stale.code, "NO_ERROR"); +assert.notEqual(production.malformed.code, "NO_ERROR"); + +const receipt = { + schemaVersion: 1, + task: "WBV2-P11-002", + operation: "MODIFIER_PARAMETER_APPLY_FAMILY_RECEIPT", + status: "PASS", + browser: "chromium", + queueMutation: false, + source: { task: "WBV2-P4-001", manifest: sourceManifestPath, manifestSha256: sha256(sourceManifestPath), report: sourceReportPath, reportSha256: sha256(sourceReportPath), desktopExact: true, wasmExact: true, sourceSaveReopenExact: true }, + engine: { receipt: engineReceiptPath, receiptSha256: sha256(engineReceiptPath), compiledWasmBound: engineReceipt.assertions.compiledWasmBound, realEngineMainMutation: engineReceipt.assertions.realEngineMainMutation }, + production: { report: productionPath, reportSha256: sha256(productionPath), secondReport: secondProductionPath, secondReportSha256: sha256(secondProductionPath), deterministic: true, meshId: production.meshId, modifierUuid: production.modifierUuid, disabledRevision: production.disabledRevision, appliedRevision: production.appliedRevision, profile: { mode: production.simplify.mode, ratio: production.simplify.ratio, attributePolicy: "PRESERVE" }, before: production.before, after: production.after, reopened: production.reopened, exactSaveReopen: production.exactSaveReopen, stale: production.stale, malformed: production.malformed }, + assertions: { parameterMutation: "DECIMATE_COLLAPSE", evaluatedApply: true, mainMutation: "CHANGED", revisionDelta: 1, saveReopenExact: true, dependencyBlockHandled: true, staleProfileRejected: true, malformedProfileRejected: true, historicalReproduction: false }, + nextTask: "WBV2-P11-003", +}; +if (!write) { + process.stdout.write("wbv2-modifier-parameter-receipt-ok task=WBV2-P11-002 apply=EXACT saveReopen=EXACT negatives=2 deterministic=true next=WBV2-P11-003\n"); + process.exit(0); +} +fs.mkdirSync(absolute(outputRoot), { recursive: true }); +fs.writeFileSync(absolute(reportPath), `${JSON.stringify(receipt, null, 2)}\n`); +fs.writeFileSync(absolute(statusPath), `# WBV2-P11-002 status\n\n- task: \`WBV2-P11-002\`; parent: \`WBV2-P11-001\`; status: \`done\`\n- dependency preparation: all active modifiers disabled; revision: \`1 -> 4\`\n- DECIMATE apply: revision \`4 -> 5\`; vertex/triangle counts reduced\n- save/reopen: \`EXACT\`; stale profile and malformed ratio rejected\n- nextTask: \`WBV2-P11-003\`\n\nThe bounded Modifier parameter/apply operation executes through the compiled WebEngine WASM Main. The dependency block is handled explicitly before apply; failed profile inputs leave the applied Main unchanged. This remains an engine-bound capability slice and does not claim complete modifier inventory parity or historical byte reproduction.\n`); +const previousPlan = readJson("tests/golden/WBV2-P11-001/module-expansion-task-plan.json"); +const nextPlan = structuredClone(previousPlan); +nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P11-001/module-expansion-task-plan.json", sha256: sha256("tests/golden/WBV2-P11-001/module-expansion-task-plan.json") }; +nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P11-002" ? { ...task, status: "done", ready: false } : task.id === "WBV2-P11-003" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); +fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +const nextCardPath = "docs/tasks/WBV2-P11-003.md"; +fs.writeFileSync(absolute(nextCardPath), read(nextCardPath).replace("- status: planned", "- status: in_progress")); +execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" }); +execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P11-002", "--write"], { cwd: root, stdio: "inherit" }); +const artifactPaths = { parentManifest: parentPath, sourceManifest: sourceManifestPath, sourceReport: sourceReportPath, engineReceipt: engineReceiptPath, production: productionPath, productionSecond: secondProductionPath, e2e: "web/tests/e2e/wbv2-modifier-parameter-production.spec.ts", protocol: "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", client: "web/app/src/engine-client/WebEngineClient.ts", generator: "tools/web/generate-wbv2-modifier-parameter-receipt.mjs", report: reportPath, status: statusPath, parityPlan: planPath, taskContext: `${outputRoot}/task-context.json` }; +const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }])); +const manifest = { schemaVersion: 1, task: "WBV2-P11-002", parentTask: "WBV2-P11-001", operation: "MODIFIER_PARAMETER_APPLY_FAMILY_RECEIPT", status: "done", enablingTask: false, parityStateChange: true, runtime: "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", artifacts, assertions: { parameterMutation: "DECIMATE_COLLAPSE", evaluatedApply: true, realEngineMainMutation: true, saveReopen: "EXACT", negativeCases: 2, dependencyBlockHandled: true, deterministic: true, historicalReproduction: false }, nextTask: "WBV2-P11-003" }; +fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P11-003` |") + .replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P11-002/manifest.json` |") + .replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P11-003.md`](tasks/WBV2-P11-003.md) |"); +fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTaskFile = read("nextTask.md"); +nextTaskFile = nextTaskFile.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P11-003` |") + .replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P11-002/manifest.json` |") + .replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P11-003.md` |") + .replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P11-004` |") + .replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-asset-link-override-production.spec.ts` |"); +fs.writeFileSync(absolute("nextTask.md"), nextTaskFile); +process.stdout.write(`wbv2-modifier-parameter-receipt-written task=WBV2-P11-002 apply=EXACT saveReopen=EXACT negatives=2 deterministic=true next=WBV2-P11-003 artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-module-expansion-root.mjs b/tools/web/generate-wbv2-module-expansion-root.mjs new file mode 100644 index 000000000..21a5b534b --- /dev/null +++ b/tools/web/generate-wbv2-module-expansion-root.mjs @@ -0,0 +1,89 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { execFileSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const absolute = (file) => path.join(root, file); +const read = (file) => fs.readFileSync(absolute(file), "utf8"); +const readJson = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const p10ManifestPath = "tests/golden/WBV2-P10-003/manifest.json"; +const p10ReportPath = "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json"; +const p10StatusPath = "docs/status/WBV2-P10-003.md"; +const outputRoot = "tests/golden/WBV2-P11-000"; +const planPath = `${outputRoot}/module-expansion-task-plan.json`; +const reportPath = `${outputRoot}/module-expansion-root-report.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const rootStatusPath = "docs/status/WBV2-P11-000.md"; + +const p10 = readJson(p10ManifestPath); +const p10Report = readJson(p10ReportPath); +assert.equal(p10.task, "WBV2-P10-003"); +assert.equal(p10.status, "done"); +assert.ok(p10.nextTask === null || p10.nextTask === "WBV2-P11-000"); +assert.equal(p10Report.task, "WBV2-P10-003"); +assert.equal(p10Report.status, "PASS"); +assert.equal(p10Report.assertions.historicalReproduction, false); +for (const artifact of Object.values(p10.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); + +const basePlan = readJson("tests/golden/WBV2-P10-003/native-parity-task-plan.json"); +assert.equal(basePlan.planId, "BLENDER_WEB_PARITY_V2_NATIVE_ENGINE_EPOCH_1"); +const tasks = basePlan.tasks.map((task) => ({ ...task, ready: false, status: task.id === "WBV2-P10-003" ? "done" : task.status })); +const p11 = [ + { id: "WBV2-P11-000", phase: "P11", title: "authorize_module_expansion_continuation", kind: "enabling", owner: "PROGRAM", dependsOn: ["WBV2-P10-003"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p11-governance", gate: "G7", card: "docs/tasks/WBV2-P11-000.md", behavior: "Authorize deeper module production after real native/WASM engine binding and the first aggregate matrix.", outputs: ["continuation root", "module expansion plan", "scope limits"], acceptance: ["P10 evidence remains hash-bound", "one expansion task is active", "full historical reproduction remains false"], status: "done", ready: false, queueMutationAllowed: true }, + { id: "WBV2-P11-001", phase: "P11", title: "mesh_topology_operation_family", kind: "feature", owner: "MESH", dependsOn: ["WBV2-P11-000"], parityId: "MESH.EDIT_TOPOLOGY_FAMILY", implementationClass: "LOCAL_EXACT", parallelGroup: "p11-mesh", gate: "G7", card: "docs/tasks/WBV2-P11-001.md", behavior: "Execute merge, dissolve, extrude, inset, bevel, and loop-cut through the real Blender WASM Main and preserve each result through save/reopen.", outputs: ["topology receipt", "negative matrix", "manifest"], acceptance: ["six mesh operations mutate Main", "revision increments exactly once", "save/reopen preserves topology counts", "invalid selection and incompatible configuration fail closed"], status: "in_progress", ready: true, queueMutationAllowed: false }, + { id: "WBV2-P11-002", phase: "P11", title: "modifier_parameter_apply_family", kind: "feature", owner: "MODIFIER", dependsOn: ["WBV2-P11-001"], parityId: "MODIFIER.PARAMETER_APPLY_FAMILY", implementationClass: "LOCAL_EXACT", parallelGroup: "p11-modifier", gate: "G7", card: "docs/tasks/WBV2-P11-002.md", behavior: "Extend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.", outputs: ["modifier parameter receipt", "negative matrix", "manifest"], acceptance: ["parameter mutation is native/WASM bound", "apply result is evaluated", "save/reopen is exact", "dependency and stale inputs fail closed"], status: "planned", ready: false, queueMutationAllowed: false }, + { id: "WBV2-P11-003", phase: "P11", title: "asset_link_override_reload_family", kind: "feature", owner: "ASSET", dependsOn: ["WBV2-P11-002"], parityId: "ASSET.LINK_OVERRIDE_RELOAD_FAMILY", implementationClass: "LOCAL_EXACT", parallelGroup: "p11-asset", gate: "G7", card: "docs/tasks/WBV2-P11-003.md", behavior: "Extend the real Asset Main path from append to link, override, reload, and missing-library boundaries.", outputs: ["asset ownership receipt", "negative matrix", "manifest"], acceptance: ["source ownership is preserved", "override is local and hash-bound", "reload revision is checked", "missing source remains explicit"], status: "planned", ready: false, queueMutationAllowed: false }, + { id: "WBV2-P11-004", phase: "P11", title: "recompute_engine_module_gate", kind: "enabling", owner: "RELEASE", dependsOn: ["WBV2-P11-003"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p11-release", gate: "G8", card: "docs/tasks/WBV2-P11-004.md", behavior: "Recompute engine-bound module parity from P10 and P11 receipts without claiming whole-inventory completion.", outputs: ["engine module gate", "limited release declaration", "manifest"], acceptance: ["only engine-bound claims are emitted", "inventory remainder is explicit", "provenance epoch 2 remains authorized rebaseline only", "full historical reproduction remains false"], status: "planned", ready: false, queueMutationAllowed: false }, +]; +const plan = { ...basePlan, planId: "BLENDER_WEB_PARITY_V2_MODULE_EXPANSION_EPOCH_1", status: "ACTIVE_MODULE_EXPANSION_QUEUE", authority: "queue_reactivated_after_p10_engine_matrix", recoveryRoot: "WBV2-P11-000", parentRecoveryPlan: { path: "tests/golden/WBV2-P10-003/native-parity-task-plan.json", sha256: sha256("tests/golden/WBV2-P10-003/native-parity-task-plan.json") }, tasks: [...tasks, ...p11] }; + +fs.mkdirSync(absolute(outputRoot), { recursive: true }); +fs.writeFileSync(absolute(planPath), `${JSON.stringify(plan, null, 2)}\n`); +const report = { schemaVersion: 1, task: "WBV2-P11-000", operation: "AUTHORIZE_MODULE_EXPANSION_CONTINUATION", status: "PASS", parent: { task: p10.task, manifest: p10ManifestPath, manifestSha256: sha256(p10ManifestPath), previousDecision: p10Report.operation, fullHistoricalReproduction: p10Report.assertions.historicalReproduction }, continuation: { root: "WBV2-P11-000", firstTask: "WBV2-P11-001", plannedTasks: 5, scope: ["MESH_TOPOLOGY", "MODIFIER_PARAMETER_APPLY", "ASSET_LINK_OVERRIDE_RELOAD", "ENGINE_MODULE_GATE"], browser: "chromium", nativeEngineAlreadyBound: true }, policy: { historicalEvidencePreserved: true, authorizedRebaselineOnly: true, engineClaimsEvidenceBound: true, fullHistoricalReproduction: false, inventoryRemainderExplicit: true }, nextTask: "WBV2-P11-001" }; +fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P11-000.md"), `# WBV2-P11-000: module expansion continuation root\n\n- task: WBV2-P11-000\n- parent: WBV2-P10-003\n- status: done\n- gap: workflow:authorize_module_expansion_continuation\n- ownerFamily: PROGRAM\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nAuthorize module expansion after P10 proved the compiled native Blender/WASM engine path. P11 only advances engine-bound Mesh, Modifier, and Asset behavior; it does not claim complete Blender parity or historical byte reproduction.\n\n## 验收\n\n- \`node tools/web/generate-wbv2-module-expansion-root.mjs\`\n- \`node tools/web/check-execution-control-plane.mjs\`\n- \`node tools/web/check-v2-task-index.mjs\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P11-000/\`\n- Manifest: \`tests/golden/WBV2-P11-000/manifest.json\`\n- Rollback: restore P10-003 as queue parent without rewriting P7-P10 evidence.\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P11-001.md"), `# WBV2-P11-001: Mesh topology operation family\n\n- task: WBV2-P11-001\n- parent: WBV2-P11-000\n- status: in_progress\n- gap: workflow:mesh_topology_operation_family\n- ownerFamily: MESH\n- targetImplementationClass: LOCAL_EXACT\n\n## 目标\n\nExecute merge, dissolve, extrude, inset, bevel, and loop-cut through the real compiled WebEngine WASM Main and preserve each result through save/reopen.\n\n## 输入与范围\n\n- Mesh fixture: \`tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend\`\n- Desktop oracle: \`tests/golden/WBV2-P2-003/mesh-edit-desktop-report.json\`\n- WASM source report: \`tests/golden/WBV2-P2-003/mesh-edit-report.json\`\n- Client: \`web/app/src/engine-client/WebEngineClient.ts\`\n- Test: \`web/tests/e2e/wbv2-mesh-topology-production.spec.ts\`\n\n## 验收\n\n- \`npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-topology-production.spec.ts\`\n- \`node tools/web/generate-wbv2-mesh-topology-receipt.mjs --write\`\n- \`node tools/web/check-task-context.mjs --task WBV2-P11-001 --write\`\n\nMalformed or unsupported operation, invalid selection, stale revision, non-Chromium execution, non-exact save/reopen, or missing Main mutation must keep in_progress and must not advance nextTask.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P11-001/\`\n- Status: \`docs/status/WBV2-P11-001.md\`\n- Manifest: \`tests/golden/WBV2-P11-001/manifest.json\`\n- Rollback: restore P11-000 as queue parent without modifying P10 evidence.\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P11-002.md"), `# WBV2-P11-002: Modifier parameter and apply family\n\n- task: WBV2-P11-002\n- parent: WBV2-P11-001\n- status: planned\n- gap: workflow:modifier_parameter_apply_family\n- ownerFamily: MODIFIER\n- targetImplementationClass: LOCAL_EXACT\n\n## 目标\n\nExtend the real Modifier Main path from enable/disable to bounded parameter and apply transactions.\n\n## 输入与范围\n\n- Modifier fixture: \`tests/files/web/generated/WBV2-P4-001-MODIFIER.DECLARED_SLICES.blend\`\n- Existing native receipt: \`tests/golden/WBV2-P10-002/native-engine-receipt-report.json\`\n- Modifier protocol: \`blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp\`\n\n## 验收\n\n- \`npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-modifier-parameter-production.spec.ts\`\n- \`node tools/web/generate-wbv2-modifier-parameter-receipt.mjs --write\`\n- \`node tools/web/check-task-context.mjs --task WBV2-P11-002 --write\`\n\nMalformed, unsupported modifier, stale revision, failed apply, non-exact save/reopen, or missing evaluated Main mutation must keep in_progress and must not advance nextTask.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P11-002/\`\n- Manifest: \`tests/golden/WBV2-P11-002/manifest.json\`\n- Rollback: restore P11-001 as queue parent without modifying Mesh evidence.\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P11-003.md"), `# WBV2-P11-003: Asset link, override, and reload family\n\n- task: WBV2-P11-003\n- parent: WBV2-P11-002\n- status: planned\n- gap: workflow:asset_link_override_reload_family\n- ownerFamily: ASSET\n- targetImplementationClass: LOCAL_EXACT\n\n## 目标\n\nExtend the real Asset Main path from append to link, local override, reload, and missing-library boundaries.\n\n## 输入与范围\n\n- Asset fixture: \`tests/files/web/generated/WBV2-P3-005-ASSET.LIBRARY_OPERATIONS.blend\`\n- Source library: \`tests/files/web/generated/WBV2P3005Library.blend\`\n- Existing append receipt: \`tests/golden/WBV2-P10-002/native-engine-receipt-report.json\`\n\n## 验收\n\n- \`npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-asset-link-override-production.spec.ts\`\n- \`node tools/web/generate-wbv2-asset-link-override-receipt.mjs --write\`\n- \`node tools/web/check-task-context.mjs --task WBV2-P11-003 --write\`\n\nMalformed binding, stale source revision, ownership violation, missing resource, non-Chromium execution, or non-exact save/reopen must keep in_progress and must not advance nextTask.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P11-003/\`\n- Status: \`docs/status/WBV2-P11-003.md\`\n- Manifest: \`tests/golden/WBV2-P11-003/manifest.json\`\n- Rollback: restore P11-002 as queue parent without modifying Mesh or Modifier evidence.\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P11-004.md"), `# WBV2-P11-004: engine module parity gate\n\n- task: WBV2-P11-004\n- parent: WBV2-P11-003\n- status: planned\n- gap: workflow:recompute_engine_module_gate\n- ownerFamily: RELEASE\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nRecompute engine-bound module claims from P10 and P11 receipts without claiming whole-inventory completion.\n\n## 输入与范围\n\n- P10 engine receipt: \`tests/golden/WBV2-P10-002/native-engine-receipt-report.json\`\n- P10 module matrix: \`tests/golden/WBV2-P10-003/module-matrix-receipt-report.json\`\n- P11 Mesh/Modifier/Asset receipts\n- Provenance approval: \`docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json\`\n\n## 验收\n\n- \`node tools/web/generate-wbv2-engine-module-gate.mjs --write\`\n- \`node tools/web/check-task-context.mjs --task WBV2-P11-004 --write\`\n\nMissing receipt, hash drift, unsupported browser, false inventory completion, false historical reproduction, or undeclared capability claim must keep in_progress and must not advance nextTask.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P11-004/\`\n- Status: \`docs/status/WBV2-P11-004.md\`\n- Manifest: \`tests/golden/WBV2-P11-004/manifest.json\`\n- Rollback: restore P11-003 as queue parent without modifying engine receipts.\n`); +fs.writeFileSync(absolute(rootStatusPath), `# WBV2-P11-000 status\n\n- task: \`WBV2-P11-000\`; parent: \`WBV2-P10-003\`; status: \`done\`\n- nextTask: \`WBV2-P11-001\`\n\nModule expansion is authorized after P10 bound the compiled Blender native/WASM engine. P11 remains evidence-bound, Chromium-only, and explicit about the inventory remainder and authorized provenance baseline.\n`); + +// Add an authorized continuation to the terminal P10 manifest without changing +// its completed matrix evidence or historical classification. +p10.nextTask = "WBV2-P11-000"; +p10.continuation = { authorized: true, root: "WBV2-P11-000", scope: "MODULE_EXPANSION" }; +p10Report.nextTask = "WBV2-P11-000"; +p10Report.policy = { ...(p10Report.policy ?? {}), terminalQueuePointer: false, authorizedContinuation: "WBV2-P11-000" }; +fs.writeFileSync(absolute(p10ReportPath), `${JSON.stringify(p10Report, null, 2)}\n`); +const currentP10Status = read(p10StatusPath).trim(); +fs.writeFileSync(absolute(p10StatusPath), currentP10Status.includes("authorized continuation: `WBV2-P11-000`") ? `${currentP10Status}\n` : `${currentP10Status}\n- authorized continuation: \`WBV2-P11-000\`\n\nModule expansion may continue under a new manifest root. This does not change the P10 evidence or the authorized-rebaseline-only release scope.\n`); +fs.writeFileSync(absolute(p10ManifestPath), `${JSON.stringify(p10, null, 2)}\n`); +execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P10-003", "--write"], { cwd: root, stdio: "pipe" }); +p10.artifacts = Object.fromEntries(Object.entries(p10.artifacts).map(([name, artifact]) => [name, { ...artifact, sha256: sha256(artifact.path) }])); +fs.writeFileSync(absolute(p10ManifestPath), `${JSON.stringify(p10, null, 2)}\n`); + +const artifactPaths = { parentManifest: p10ManifestPath, parentReport: p10ReportPath, approval: "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", plan: planPath, report: reportPath, rootCard: "docs/tasks/WBV2-P11-000.md", rootStatus: rootStatusPath, activeCard: "docs/tasks/WBV2-P11-001.md" }; +const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }])); +const manifest = { schemaVersion: 1, task: "WBV2-P11-000", parentTask: "WBV2-P10-003", operation: "AUTHORIZE_MODULE_EXPANSION_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, artifacts, assertions: { p10EvidencePreserved: true, nativeEngineAlreadyBound: true, moduleExpansionScope: ["MESH_TOPOLOGY", "MODIFIER_PARAMETER_APPLY", "ASSET_LINK_OVERRIDE_RELOAD"], authorizedRebaselineOnly: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P11-001" }; +fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" }); +let queue = read("docs/EXECUTION_QUEUE.md"); +queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P11-001` |") + .replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P11-000/manifest.json` |") + .replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P11-001.md`](tasks/WBV2-P11-001.md) |"); +fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +// Keep the human-facing continuation snapshot aligned with the authoritative +// queue; the queue and parent manifest remain the machine sources of truth. +let nextTaskFile = read("nextTask.md"); +nextTaskFile = nextTaskFile.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P11-001` |") + .replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |") + .replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P11-000/manifest.json` |") + .replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P11-001.md` |") + .replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P11-002` |") + .replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-topology-production.spec.ts` |"); +fs.writeFileSync(absolute("nextTask.md"), nextTaskFile); +process.stdout.write("wbv2-module-expansion-root-ok root=WBV2-P11-000 next=WBV2-P11-001 scope=MESH_TOPOLOGY,MODIFIER_PARAMETER_APPLY,ASSET_LINK_OVERRIDE_RELOAD\n"); diff --git a/web/tests/e2e/wbv2-asset-link-override-production.spec.ts b/web/tests/e2e/wbv2-asset-link-override-production.spec.ts new file mode 100644 index 000000000..3a0174546 --- /dev/null +++ b/web/tests/e2e/wbv2-asset-link-override-production.spec.ts @@ -0,0 +1,77 @@ +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { expect, test } from "@playwright/test"; +import { computeLibraryAppendClosureSha256 } from "../../protocol/library-main-append"; +import { createLibraryOperationBinding, createLibrarySourceIdentity, LIBRARY_OPERATION_IDENTITY_SCHEMA } from "../../protocol/library-operation-identity"; + +const root = path.resolve(import.meta.dirname, "../../.."); +const evidenceRoot = path.join(root, "tests/golden/WBV2-P11-003"); +const linkedFixture = fs.readFileSync(path.join(root, "tests/files/web/generated/WBV2-P3-005-ASSET.LIBRARY_OPERATIONS.blend")); +const emptyFixture = fs.readFileSync(path.join(root, "tests/files/web/empty.blend")); +const sourceLibrary = fs.readFileSync(path.join(root, "tests/files/web/generated/WBV2P3005Library.blend")); +const sha256 = (bytes: Uint8Array): string => crypto.createHash("sha256").update(bytes).digest("hex"); + +test("WBV2-P11-003 enforces linked ownership and local append through compiled WASM Main", async ({ page }) => { + test.setTimeout(180_000); + await page.goto("/"); + const closure = { object: "Object/WBV2P3005AppendObject", mesh: "Mesh/WBV2P3005AppendMesh", material: "Material/WBV2P3005AppendMaterial", image: "Image/WBV2P3005AppendImage" } as const; + const sourceSha256 = sha256(sourceLibrary); + const sourceIdentity = await createLibrarySourceIdentity({ sourceLocator: "project-assets/libraries/WBV2P3005Library.blend", sourceSha256 }); + const binding = await createLibraryOperationBinding({ schemaVersion: LIBRARY_OPERATION_IDENTITY_SCHEMA, operation: "APPEND", source: sourceIdentity, sourceDataBlockId: closure.object, owner: { kind: "LOCAL_MAIN", projectId: "project:wbv2-p11-003", localDataBlockId: closure.object }, readOnly: false, referenceReadOnly: false, sourceGeneration: 1, sourceRevision: 0, dependencyClosureSha256: await computeLibraryAppendClosureSha256(closure) }); + const result = await page.evaluate(async (input) => { + const { WebEngineClient } = await import("/src/engine-client/WebEngineClient.ts"); + const buffer = (values: number[]): ArrayBuffer => Uint8Array.from(values).buffer; + const digest = async (value: ArrayBuffer): Promise => { const hash = await crypto.subtle.digest("SHA-256", value); return Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join(""); }; + const shapeError = (error: any) => ({ code: error?.code, message: error?.message }); + const linkedClient = new WebEngineClient({ timeoutMs: 60_000 }); + const appendClient = new WebEngineClient({ timeoutMs: 60_000 }); + const reopenedClient = new WebEngineClient({ timeoutMs: 60_000 }); + try { + const linked = await linkedClient.openBlend(buffer(input.linkedBytes)); + const linkedObject: any = linked.snapshot.nodes.find((candidate: any) => candidate.id.includes("WBV2P3005LinkedObject")); + const linkedBefore = { id: linkedObject?.id ?? null, visible: linkedObject?.visible ?? null, objectPresent: Boolean(linkedObject), libraries: linked.snapshot.libraries ?? [], libraryStatus: linked.snapshot.libraryStatus }; + const linkedMutation = linkedObject + ? await linkedClient.applyCommand({ type: "setObjectVisibility", objectId: linkedObject.id, visible: !linkedObject.visible, baseRevision: linked.snapshot.revision } as any).then(() => ({ code: "NO_ERROR" })).catch(shapeError) + : { code: "LINKED_LIBRARY_REQUIRED", message: "linked object withheld while external library is unavailable" }; + const linkedAfterSnapshot = await linkedClient.snapshot(); + const linkedAfter = linkedObject ? linkedAfterSnapshot.snapshot.nodes.find((candidate: any) => candidate.id === linkedObject.id) : undefined; + + const opened = await appendClient.openBlend(buffer(input.emptyBytes)); + const baseRevision = opened.snapshot.revision; + const appended = await appendClient.appendLibraryObject(buffer(input.sourceBytes), { schemaVersion: 1, baseRevision, binding: input.binding, expectedClosure: input.closure }); + const localClosure = (snapshot: any) => ({ object: snapshot.nodes.find((candidate: any) => candidate.id === "object:WBV2P3005AppendObject"), mesh: snapshot.meshes.find((candidate: any) => candidate.id === "mesh:WBV2P3005AppendMesh"), material: snapshot.materials.find((candidate: any) => candidate.id === "material:WBV2P3005AppendMaterial"), image: snapshot.images.find((candidate: any) => candidate.id === "image:WBV2P3005AppendImage") }); + const local = localClosure(appended.snapshot); + const saved = await appendClient.saveBlend(); + const savedSha256 = await digest(saved.slice(0)); + const reopened = await reopenedClient.openBlend(saved.slice(0)); + const reopenedLocal = localClosure(reopened.snapshot); + const stale = await appendClient.appendLibraryObject(buffer(input.sourceBytes), { schemaVersion: 1, baseRevision, binding: input.binding, expectedClosure: input.closure }).then(() => ({ code: "NO_ERROR" })).catch(shapeError); + const afterStale = (await appendClient.snapshot()).snapshot.revision; + return { linked: { before: linkedBefore, mutation: linkedMutation, after: { id: linkedAfter?.id ?? null, visible: linkedAfter?.visible ?? null, objectPresent: Boolean(linkedAfter) }, revisionBefore: linked.snapshot.revision, revisionAfter: linkedAfterSnapshot.snapshot.revision }, append: { baseRevision, appendedRevision: appended.snapshot.revision, receipt: appended.receipt, local: { object: local.object && { id: local.object.id, type: local.object.type, dataId: local.object.dataId }, mesh: local.mesh && { id: local.mesh.id, materialSlotIds: local.mesh.materialSlotIds, vertexCount: local.mesh.vertexCount }, material: local.material && { id: local.material.id, imageIds: local.material.imageIds ?? local.material.nodes?.flatMap((node: any) => node.imageId ? [node.imageId] : []) }, image: local.image && { id: local.image.id, libraryLinked: local.image.libraryLinked, packed: local.image.packed, assetStatus: local.image.assetStatus } }, reopened: { object: Boolean(reopenedLocal.object), mesh: Boolean(reopenedLocal.mesh), material: Boolean(reopenedLocal.material), image: reopenedLocal.image && { libraryLinked: reopenedLocal.image.libraryLinked, packed: reopenedLocal.image.packed } }, saveReopenExact: Boolean(reopenedLocal.object && reopenedLocal.mesh && reopenedLocal.material && reopenedLocal.image?.libraryLinked === false && reopenedLocal.image?.packed === true), savedSha256, sourceSha256: await digest(buffer(input.sourceBytes)), stale, revisionAfterStale: afterStale } }; + } + finally { linkedClient.terminate(); appendClient.terminate(); reopenedClient.terminate(); } + }, { linkedBytes: Array.from(linkedFixture), emptyBytes: Array.from(emptyFixture), sourceBytes: Array.from(sourceLibrary), closure, binding }); + fs.mkdirSync(evidenceRoot, { recursive: true }); + const output = process.env.WBV2_ASSET_LINK_OVERRIDE_REPORT ?? "asset-link-override-production.json"; + fs.writeFileSync(path.join(evidenceRoot, output), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P11-003", operation: "ASSET_LINK_OVERRIDE_RELOAD_FAMILY_CHROMIUM", browser: "chromium", queueMutation: false, ...result }, null, 2)}\n`); + expect(result.linked.before.libraryStatus).toBe("AVAILABLE"); + expect(result.linked.before.libraries.length).toBeGreaterThan(0); + expect(result.linked.before.libraries.every((library: any) => library.status === "EXTERNAL_REQUIRED" && library.readOnly === true)).toBe(true); + expect(result.linked.mutation.code).not.toBe("NO_ERROR"); + expect(result.linked.before.objectPresent).toBe(false); + expect(result.linked.after.objectPresent).toBe(false); + expect(result.linked.after.visible).toBe(result.linked.before.visible); + expect(result.linked.revisionAfter).toBe(result.linked.revisionBefore); + expect(result.append.appendedRevision).toBe(result.append.baseRevision + 1); + expect(result.append.receipt.operation).toBe("APPEND"); + expect(result.append.receipt.mapping.every((entry: any) => entry.owner === "LOCAL_MAIN" && entry.readOnly === false && entry.source === entry.local)).toBe(true); + expect(result.append.local.object.type).toBe("MESH"); + expect(result.append.local.mesh.vertexCount).toBe(4); + expect(result.append.local.image.libraryLinked).toBe(false); + expect(result.append.local.image.packed).toBe(true); + expect(result.append.saveReopenExact).toBe(true); + expect(result.append.stale.code).not.toBe("NO_ERROR"); + expect(result.append.stale.message).toContain("REVISION_CONFLICT"); + expect(result.append.revisionAfterStale).toBe(result.append.appendedRevision); +}); diff --git a/web/tests/e2e/wbv2-mesh-topology-production.spec.ts b/web/tests/e2e/wbv2-mesh-topology-production.spec.ts new file mode 100644 index 000000000..45a5c7387 --- /dev/null +++ b/web/tests/e2e/wbv2-mesh-topology-production.spec.ts @@ -0,0 +1,87 @@ +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { expect, test } from "@playwright/test"; + +const root = path.resolve(import.meta.dirname, "../../.."); +const evidenceRoot = path.join(root, "tests/golden/WBV2-P11-001"); +const fixturePath = path.join(root, "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend"); +const fixture = fs.readFileSync(fixturePath); +const sourceSha256 = crypto.createHash("sha256").update(fixture).digest("hex"); + +test("WBV2-P11-001 executes the six Mesh topology operations through compiled WASM Main", async ({ page }) => { + test.setTimeout(240_000); + await page.goto("/"); + const result = await page.evaluate(async (input) => { + const { WebEngineClient } = await import("/src/engine-client/WebEngineClient.ts"); + const operations = [ + { label: "MERGE", meshId: "mesh:WBV2P2003MergeMesh", selectionMode: "VERT", elementIndices: [0, 1] }, + { label: "DISSOLVE", meshId: "mesh:WBV2P2003DissolveMesh", selectionMode: "EDGE", elementIndices: [0] }, + { label: "EXTRUDE", meshId: "mesh:WBV2P2003ExtrudeMesh", selectionMode: "FACE", elementIndices: [0], offset: [0, 0, 1] }, + { label: "INSET", meshId: "mesh:WBV2P2003InsetMesh", selectionMode: "FACE", elementIndices: [0], amount: 0.2 }, + { label: "BEVEL", meshId: "mesh:WBV2P2003BevelMesh", selectionMode: "EDGE", elementIndices: [0], amount: 0.1, segments: 2 }, + { label: "LOOP_CUT", meshId: "mesh:WBV2P2003LoopCutMesh", selectionMode: "EDGE", elementIndices: [0], segments: 1 }, + ]; + const summary = (snapshot: any, meshId: string) => { + const mesh = snapshot.meshes.find((candidate: any) => candidate.id === meshId); + if (!mesh) throw new Error(`mesh missing: ${meshId}`); + return { id: mesh.id, vertexCount: mesh.vertexCount, edgeCount: mesh.edgeCount, faceCount: mesh.faceCount, triangleCount: mesh.triangleCount, topology: mesh.topology }; + }; + const digest = async (value: ArrayBuffer): Promise => { const hash = await crypto.subtle.digest("SHA-256", value); return Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join(""); }; + const errors = async (client: any, commands: any[], revision: number) => { + const values = []; + for (const command of commands) { + const error = await client.applyCommand({ baseRevision: revision, ...command } as any).then(() => null).catch((caught) => ({ code: caught?.code, message: caught?.message })); + values.push(error); + } + return values; + }; + const positive = []; + for (const operation of operations) { + const client = new WebEngineClient({ timeoutMs: 60_000 }); + const reopenedClient = new WebEngineClient({ timeoutMs: 60_000 }); + try { + const opened = await client.openBlend(Uint8Array.from(input.bytes).buffer); + const before = summary(opened.snapshot, operation.meshId); + const baseRevision = opened.snapshot.revision; + const edited = await client.applyCommand({ type: "meshEdit", meshId: operation.meshId, operation: operation.label, selectionMode: operation.selectionMode, elementIndices: operation.elementIndices, ...(operation.offset ? { offset: operation.offset } : {}), ...(operation.amount === undefined ? {} : { amount: operation.amount }), ...(operation.segments === undefined ? {} : { segments: operation.segments }), baseRevision } as any); + const after = summary(edited.snapshot, operation.meshId); + const saved = await client.saveBlend(); + const savedSha256 = await digest(saved.slice(0)); + const reopened = await reopenedClient.openBlend(saved.slice(0)); + const reopenedSummary = summary(reopened.snapshot, operation.meshId); + positive.push({ operation: operation.label, meshId: operation.meshId, baseRevision, afterRevision: edited.snapshot.revision, before, after, reopened: reopenedSummary, savedSha256, exactSaveReopen: JSON.stringify(after) === JSON.stringify(reopenedSummary) }); + } + finally { client.terminate(); reopenedClient.terminate(); } + } + + const negativeClient = new WebEngineClient({ timeoutMs: 60_000 }); + try { + const opened = await negativeClient.openBlend(Uint8Array.from(input.bytes).buffer); + const revision = opened.snapshot.revision; + const before = summary(opened.snapshot, "mesh:WBV2P2003MergeMesh"); + const [invalidSelection, incompatible, stale] = await errors(negativeClient, [ + { type: "meshEdit", meshId: "mesh:WBV2P2003MergeMesh", operation: "MERGE", selectionMode: "VERT", elementIndices: [999] }, + { type: "meshEdit", meshId: "mesh:WBV2P2003MergeMesh", operation: "EXTRUDE", selectionMode: "EDGE", elementIndices: [0], offset: [0, 0, 1] }, + { type: "meshEdit", meshId: "mesh:WBV2P2003MergeMesh", operation: "MERGE", selectionMode: "VERT", elementIndices: [0, 1], baseRevision: revision - 1 }, + ], revision); + const after = summary((await negativeClient.snapshot()).snapshot, "mesh:WBV2P2003MergeMesh"); + return { sourceSha256: input.sourceSha256, operations: positive, negative: { invalidSelection, incompatible, stale, before, after, revisionBefore: revision, revisionAfter: (await negativeClient.snapshot()).snapshot.revision } }; + } + finally { negativeClient.terminate(); } + }, { bytes: Array.from(fixture), sourceSha256 }); + + fs.mkdirSync(evidenceRoot, { recursive: true }); + const output = process.env.WBV2_MESH_TOPOLOGY_REPORT ?? "mesh-topology-production.json"; + fs.writeFileSync(path.join(evidenceRoot, output), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P11-001", operation: "MESH_TOPOLOGY_OPERATION_FAMILY_CHROMIUM", browser: "chromium", queueMutation: false, ...result }, null, 2)}\n`); + expect(result.sourceSha256).toBe(sourceSha256); + expect(result.operations).toHaveLength(6); + expect(result.operations.every((entry) => entry.afterRevision === entry.baseRevision + 1 && entry.exactSaveReopen && entry.after.vertexCount > 0 && entry.after.edgeCount > 0 && entry.after.faceCount > 0)).toBe(true); + expect(result.operations.map((entry) => entry.operation)).toEqual(["MERGE", "DISSOLVE", "EXTRUDE", "INSET", "BEVEL", "LOOP_CUT"]); + expect(result.negative.invalidSelection?.code).toBe("INVALID_ARGUMENT"); + expect(result.negative.incompatible?.code).toBe("INVALID_ARGUMENT"); + expect(result.negative.stale?.code).toBe("INVALID_ARGUMENT"); + expect(result.negative.stale?.message).toContain("REVISION_CONFLICT"); + expect(result.negative.revisionAfter).toBe(result.negative.revisionBefore); + expect(result.negative.after).toEqual(result.negative.before); +}); diff --git a/web/tests/e2e/wbv2-modifier-parameter-production.spec.ts b/web/tests/e2e/wbv2-modifier-parameter-production.spec.ts new file mode 100644 index 000000000..280c78f41 --- /dev/null +++ b/web/tests/e2e/wbv2-modifier-parameter-production.spec.ts @@ -0,0 +1,65 @@ +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { expect, test } from "@playwright/test"; + +const root = path.resolve(import.meta.dirname, "../../.."); +const evidenceRoot = path.join(root, "tests/golden/WBV2-P11-002"); +const fixturePath = path.join(root, "tests/files/web/generated/WBV2-P4-001-MODIFIER.DECLARED_SLICES.blend"); +const fixture = fs.readFileSync(fixturePath); +const sourceSha256 = crypto.createHash("sha256").update(fixture).digest("hex"); + +test("WBV2-P11-002 applies a bounded Modifier parameter through compiled WASM Main", async ({ page }) => { + test.setTimeout(180_000); + await page.goto("/"); + const result = await page.evaluate(async (input) => { + const { WebEngineClient } = await import("/src/engine-client/WebEngineClient.ts"); + const summary = (snapshot: any, meshId: string) => { + const mesh = snapshot.meshes.find((candidate: any) => candidate.id === meshId); + if (!mesh) throw new Error(`mesh missing: ${meshId}`); + return { id: mesh.id, vertexCount: mesh.vertexCount, edgeCount: mesh.edgeCount, faceCount: mesh.faceCount, triangleCount: mesh.triangleCount, modifierStack: mesh.modifierStack?.map((modifier: any) => ({ uuid: modifier.uuid, type: modifier.type, enabled: modifier.enabled, evaluationStatus: modifier.evaluationStatus })) ?? [] }; + }; + const errorShape = (error: any) => ({ code: error?.code, message: error?.message }); + const client = new WebEngineClient({ timeoutMs: 60_000 }); + const reopenedClient = new WebEngineClient({ timeoutMs: 60_000 }); + try { + const opened = await client.openBlend(Uint8Array.from(input.bytes).buffer); + const mesh: any = opened.snapshot.meshes.find((candidate: any) => candidate.id === "mesh:WBV2P4001ModifierMesh"); + const decimate: any = mesh?.modifierStack?.find((candidate: any) => candidate.type === "DECIMATE"); + if (!mesh || !decimate) throw new Error("modifier fixture missing DECIMATE stack entry"); + const before = summary(opened.snapshot, mesh.id); + let disabled = { snapshot: opened } as any; + for (const activeModifier of mesh.modifierStack?.filter((candidate: any) => candidate.enabled) ?? []) { + disabled = await client.applyCommand({ type: "setModifierEnabled", meshId: mesh.id, modifierUuid: activeModifier.uuid, enabled: false, baseRevision: disabled.snapshot.revision } as any); + } + const profile = { schemaVersion: 1 as const, sourceMeshRevision: disabled.snapshot.revision, mode: "COLLAPSE" as const, ratio: 0.75, iterations: 1, attributePolicy: "PRESERVE" as const, triangulate: false, useSymmetry: false }; + const applied = await client.applyCommand({ type: "decimateMesh", meshId: mesh.id, profile } as any); + const after = summary(applied.snapshot, mesh.id); + const stale = await client.applyCommand({ type: "decimateMesh", meshId: mesh.id, profile } as any).then(() => ({ code: "NO_ERROR" })).catch(errorShape); + const afterStale = summary((await client.snapshot()).snapshot, mesh.id); + const malformed = await client.applyCommand({ type: "decimateMesh", meshId: mesh.id, profile: { ...profile, sourceMeshRevision: applied.snapshot.revision, ratio: 2 } } as any).then(() => ({ code: "NO_ERROR" })).catch(errorShape); + const afterMalformed = summary((await client.snapshot()).snapshot, mesh.id); + const saved = await client.saveBlend(); + const savedSha256 = await (async () => { const hash = await crypto.subtle.digest("SHA-256", saved.slice(0)); return Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join(""); })(); + const reopened = await reopenedClient.openBlend(saved.slice(0)); + const reopenedSummary = summary(reopened.snapshot, mesh.id); + return { sourceSha256: input.sourceSha256, meshId: mesh.id, modifierUuid: decimate.uuid, before, disabledRevision: disabled.snapshot.revision, appliedRevision: applied.snapshot.revision, simplify: applied.simplify, after, afterStale, afterMalformed, stale, malformed, savedSha256, reopened: reopenedSummary, exactSaveReopen: JSON.stringify(after) === JSON.stringify(reopenedSummary) && JSON.stringify(after) === JSON.stringify(afterStale) && JSON.stringify(after) === JSON.stringify(afterMalformed) }; + } + finally { client.terminate(); reopenedClient.terminate(); } + }, { bytes: Array.from(fixture), sourceSha256 }); + fs.mkdirSync(evidenceRoot, { recursive: true }); + const output = process.env.WBV2_MODIFIER_PARAMETER_REPORT ?? "modifier-parameter-production.json"; + fs.writeFileSync(path.join(evidenceRoot, output), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P11-002", operation: "MODIFIER_PARAMETER_APPLY_FAMILY_CHROMIUM", browser: "chromium", queueMutation: false, ...result }, null, 2)}\n`); + expect(result.sourceSha256).toBe(sourceSha256); + expect(result.disabledRevision).toBe(4); + expect(result.appliedRevision).toBe(5); + expect(result.simplify?.status).toBe("applied"); + expect(result.after.vertexCount).toBeLessThan(result.before.vertexCount); + expect(result.after.triangleCount).toBeLessThan(result.before.triangleCount); + expect(result.exactSaveReopen).toBe(true); + expect(result.stale.code).not.toBe("NO_ERROR"); + expect(result.malformed.code).not.toBe("NO_ERROR"); + expect(result.afterStale).toEqual(result.after); + expect(result.afterMalformed).toEqual(result.after); + expect(result.savedSha256).not.toBe(sourceSha256); +});