Continue WBV2 module parity through P11
This commit is contained in:
@@ -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` |
|
||||
|
||||
@@ -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.
|
||||
|
||||
6
docs/status/WBV2-P11-000.md
Normal file
6
docs/status/WBV2-P11-000.md
Normal file
@@ -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.
|
||||
9
docs/status/WBV2-P11-001.md
Normal file
9
docs/status/WBV2-P11-001.md
Normal file
@@ -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.
|
||||
9
docs/status/WBV2-P11-002.md
Normal file
9
docs/status/WBV2-P11-002.md
Normal file
@@ -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.
|
||||
9
docs/status/WBV2-P11-003.md
Normal file
9
docs/status/WBV2-P11-003.md
Normal file
@@ -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.
|
||||
12
docs/status/WBV2-P11-004.md
Normal file
12
docs/status/WBV2-P11-004.md
Normal file
@@ -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.
|
||||
24
docs/tasks/WBV2-P11-000.md
Normal file
24
docs/tasks/WBV2-P11-000.md
Normal file
@@ -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.
|
||||
35
docs/tasks/WBV2-P11-001.md
Normal file
35
docs/tasks/WBV2-P11-001.md
Normal file
@@ -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.
|
||||
32
docs/tasks/WBV2-P11-002.md
Normal file
32
docs/tasks/WBV2-P11-002.md
Normal file
@@ -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.
|
||||
33
docs/tasks/WBV2-P11-003.md
Normal file
33
docs/tasks/WBV2-P11-003.md
Normal file
@@ -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.
|
||||
33
docs/tasks/WBV2-P11-004.md
Normal file
33
docs/tasks/WBV2-P11-004.md
Normal file
@@ -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.
|
||||
12
nextTask.md
12
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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,5 +61,9 @@
|
||||
"retainedNegativeExplicit": true,
|
||||
"historicalReproduction": false
|
||||
},
|
||||
"nextTask": null
|
||||
"nextTask": "WBV2-P11-000",
|
||||
"policy": {
|
||||
"terminalQueuePointer": false,
|
||||
"authorizedContinuation": "WBV2-P11-000"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
55
tests/golden/WBV2-P11-000/manifest.json
Normal file
55
tests/golden/WBV2-P11-000/manifest.json
Normal file
@@ -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"
|
||||
}
|
||||
34
tests/golden/WBV2-P11-000/module-expansion-root-report.json
Normal file
34
tests/golden/WBV2-P11-000/module-expansion-root-report.json
Normal file
@@ -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"
|
||||
}
|
||||
1716
tests/golden/WBV2-P11-000/module-expansion-task-plan.json
Normal file
1716
tests/golden/WBV2-P11-000/module-expansion-task-plan.json
Normal file
File diff suppressed because it is too large
Load Diff
74
tests/golden/WBV2-P11-001/manifest.json
Normal file
74
tests/golden/WBV2-P11-001/manifest.json
Normal file
@@ -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"
|
||||
}
|
||||
234
tests/golden/WBV2-P11-001/mesh-topology-production.json
Normal file
234
tests/golden/WBV2-P11-001/mesh-topology-production.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
234
tests/golden/WBV2-P11-001/mesh-topology-production.second.json
Normal file
234
tests/golden/WBV2-P11-001/mesh-topology-production.second.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
245
tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json
Normal file
245
tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json
Normal file
@@ -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"
|
||||
}
|
||||
1716
tests/golden/WBV2-P11-001/module-expansion-task-plan.json
Normal file
1716
tests/golden/WBV2-P11-001/module-expansion-task-plan.json
Normal file
File diff suppressed because it is too large
Load Diff
185
tests/golden/WBV2-P11-001/task-context.json
Normal file
185
tests/golden/WBV2-P11-001/task-context.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
79
tests/golden/WBV2-P11-002/manifest.json
Normal file
79
tests/golden/WBV2-P11-002/manifest.json
Normal file
@@ -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"
|
||||
}
|
||||
169
tests/golden/WBV2-P11-002/modifier-parameter-production.json
Normal file
169
tests/golden/WBV2-P11-002/modifier-parameter-production.json
Normal file
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
142
tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json
Normal file
142
tests/golden/WBV2-P11-002/modifier-parameter-receipt-report.json
Normal file
@@ -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"
|
||||
}
|
||||
1716
tests/golden/WBV2-P11-002/module-expansion-task-plan.json
Normal file
1716
tests/golden/WBV2-P11-002/module-expansion-task-plan.json
Normal file
File diff suppressed because it is too large
Load Diff
170
tests/golden/WBV2-P11-002/task-context.json
Normal file
170
tests/golden/WBV2-P11-002/task-context.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
121
tests/golden/WBV2-P11-003/asset-link-override-production.json
Normal file
121
tests/golden/WBV2-P11-003/asset-link-override-production.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
78
tests/golden/WBV2-P11-003/manifest.json
Normal file
78
tests/golden/WBV2-P11-003/manifest.json
Normal file
@@ -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"
|
||||
}
|
||||
1716
tests/golden/WBV2-P11-003/module-expansion-task-plan.json
Normal file
1716
tests/golden/WBV2-P11-003/module-expansion-task-plan.json
Normal file
File diff suppressed because it is too large
Load Diff
175
tests/golden/WBV2-P11-003/task-context.json
Normal file
175
tests/golden/WBV2-P11-003/task-context.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
98
tests/golden/WBV2-P11-004/engine-module-gate-report.json
Normal file
98
tests/golden/WBV2-P11-004/engine-module-gate-report.json
Normal file
@@ -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
|
||||
}
|
||||
90
tests/golden/WBV2-P11-004/manifest.json
Normal file
90
tests/golden/WBV2-P11-004/manifest.json
Normal file
@@ -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
|
||||
}
|
||||
1716
tests/golden/WBV2-P11-004/module-expansion-task-plan.json
Normal file
1716
tests/golden/WBV2-P11-004/module-expansion-task-plan.json
Normal file
File diff suppressed because it is too large
Load Diff
177
tests/golden/WBV2-P11-004/task-context.json
Normal file
177
tests/golden/WBV2-P11-004/task-context.json
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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"]}
|
||||
|
||||
File diff suppressed because one or more lines are too long
112
tools/web/generate-wbv2-asset-link-override-receipt.mjs
Normal file
112
tools/web/generate-wbv2-asset-link-override-receipt.mjs
Normal file
@@ -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`);
|
||||
122
tools/web/generate-wbv2-engine-module-gate.mjs
Normal file
122
tools/web/generate-wbv2-engine-module-gate.mjs
Normal file
@@ -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`);
|
||||
101
tools/web/generate-wbv2-mesh-topology-receipt.mjs
Normal file
101
tools/web/generate-wbv2-mesh-topology-receipt.mjs
Normal file
@@ -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`);
|
||||
105
tools/web/generate-wbv2-modifier-parameter-receipt.mjs
Normal file
105
tools/web/generate-wbv2-modifier-parameter-receipt.mjs
Normal file
@@ -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`);
|
||||
89
tools/web/generate-wbv2-module-expansion-root.mjs
Normal file
89
tools/web/generate-wbv2-module-expansion-root.mjs
Normal file
@@ -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");
|
||||
77
web/tests/e2e/wbv2-asset-link-override-production.spec.ts
Normal file
77
web/tests/e2e/wbv2-asset-link-override-production.spec.ts
Normal file
@@ -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<string> => { 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);
|
||||
});
|
||||
87
web/tests/e2e/wbv2-mesh-topology-production.spec.ts
Normal file
87
web/tests/e2e/wbv2-mesh-topology-production.spec.ts
Normal file
@@ -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<string> => { 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);
|
||||
});
|
||||
65
web/tests/e2e/wbv2-modifier-parameter-production.spec.ts
Normal file
65
web/tests/e2e/wbv2-modifier-parameter-production.spec.ts
Normal file
@@ -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);
|
||||
});
|
||||
Reference in New Issue
Block a user