From 4a5c70910b07e60127ac2019320ec040ca0fa9ae Mon Sep 17 00:00:00 2001 From: mes123456 Date: Fri, 28 Aug 2026 12:19:18 +0800 Subject: [PATCH] Advance deduplicated lighting capability coverage --- docs/EXECUTION_QUEUE.md | 6 +- docs/status/WBV2-P15-000.md | 9 + docs/status/WBV2-P15-001.md | 11 + docs/status/WBV2-P15-002.md | 11 + docs/status/WBV2-P15-003.md | 10 + docs/tasks/WBV2-P15-000.md | 24 + docs/tasks/WBV2-P15-001.md | 34 + docs/tasks/WBV2-P15-002.md | 34 + docs/tasks/WBV2-P15-003.md | 34 + nextTask.md | 8 +- .../WBV2-P15-000/lights-root-report.json | 35 + .../golden/WBV2-P15-000/lights-task-plan.json | 146 ++ tests/golden/WBV2-P15-000/manifest.json | 60 + .../WBV2-P15-001/lighting-candidate-set.json | 2233 +++++++++++++++++ .../lighting-selection-report.json | 66 + .../golden/WBV2-P15-001/lights-task-plan.json | 150 ++ tests/golden/WBV2-P15-001/manifest.json | 76 + tests/golden/WBV2-P15-001/task-context.json | 172 ++ .../lighting-fields-production.json | 97 + .../lighting-fields-production.second.json | 97 + .../lighting-fields-receipt-report.json | 135 + .../golden/WBV2-P15-002/lights-task-plan.json | 150 ++ tests/golden/WBV2-P15-002/manifest.json | 81 + tests/golden/WBV2-P15-002/task-context.json | 169 ++ .../WBV2-P15-003/lighting-gate-report.json | 108 + .../golden/WBV2-P15-003/lights-task-plan.json | 150 ++ tests/golden/WBV2-P15-003/manifest.json | 74 + tests/golden/WBV2-P15-003/task-context.json | 168 ++ tests/golden/WBV2/task-catalog.jsonl | 8 +- tests/golden/WBV2/task-index.json | 2 +- tools/web/generate-wbv2-lighting-gate.mjs | 41 + tools/web/generate-wbv2-lighting-receipt.mjs | 49 + .../web/generate-wbv2-lighting-selection.mjs | 53 + tools/web/generate-wbv2-lights-root.mjs | 53 + .../wbv2-lighting-fields-production.spec.ts | 59 + 35 files changed, 4601 insertions(+), 12 deletions(-) create mode 100644 docs/status/WBV2-P15-000.md create mode 100644 docs/status/WBV2-P15-001.md create mode 100644 docs/status/WBV2-P15-002.md create mode 100644 docs/status/WBV2-P15-003.md create mode 100644 docs/tasks/WBV2-P15-000.md create mode 100644 docs/tasks/WBV2-P15-001.md create mode 100644 docs/tasks/WBV2-P15-002.md create mode 100644 docs/tasks/WBV2-P15-003.md create mode 100644 tests/golden/WBV2-P15-000/lights-root-report.json create mode 100644 tests/golden/WBV2-P15-000/lights-task-plan.json create mode 100644 tests/golden/WBV2-P15-000/manifest.json create mode 100644 tests/golden/WBV2-P15-001/lighting-candidate-set.json create mode 100644 tests/golden/WBV2-P15-001/lighting-selection-report.json create mode 100644 tests/golden/WBV2-P15-001/lights-task-plan.json create mode 100644 tests/golden/WBV2-P15-001/manifest.json create mode 100644 tests/golden/WBV2-P15-001/task-context.json create mode 100644 tests/golden/WBV2-P15-002/lighting-fields-production.json create mode 100644 tests/golden/WBV2-P15-002/lighting-fields-production.second.json create mode 100644 tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json create mode 100644 tests/golden/WBV2-P15-002/lights-task-plan.json create mode 100644 tests/golden/WBV2-P15-002/manifest.json create mode 100644 tests/golden/WBV2-P15-002/task-context.json create mode 100644 tests/golden/WBV2-P15-003/lighting-gate-report.json create mode 100644 tests/golden/WBV2-P15-003/lights-task-plan.json create mode 100644 tests/golden/WBV2-P15-003/manifest.json create mode 100644 tests/golden/WBV2-P15-003/task-context.json create mode 100644 tools/web/generate-wbv2-lighting-gate.mjs create mode 100644 tools/web/generate-wbv2-lighting-receipt.mjs create mode 100644 tools/web/generate-wbv2-lighting-selection.mjs create mode 100644 tools/web/generate-wbv2-lights-root.mjs create mode 100644 web/tests/e2e/wbv2-lighting-fields-production.spec.ts diff --git a/docs/EXECUTION_QUEUE.md b/docs/EXECUTION_QUEUE.md index 27fd25a68..f22fab904 100644 --- a/docs/EXECUTION_QUEUE.md +++ b/docs/EXECUTION_QUEUE.md @@ -13,9 +13,9 @@ | 字段 | 值 | | --- | --- | | 里程碑 | WBV2 capability workflow | -| 当前任务 | `WBV2-P14-003` | -| parent manifest | `tests/golden/WBV2-P14-002/manifest.json` | -| 任务卡 | [`tasks/WBV2-P14-003.md`](tasks/WBV2-P14-003.md) | +| 当前任务 | `WBV2-P15-003` | +| parent manifest | `tests/golden/WBV2-P15-002/manifest.json` | +| 任务卡 | [`tasks/WBV2-P15-003.md`](tasks/WBV2-P15-003.md) | | 专项验收 | `node tools/web/check-execution-control-plane.mjs` | | legacy coverage checkpoint | `M16-GAP-00282` | | legacy coverage parent | `tests/golden/M16-GAP-00281/manifest.json` | diff --git a/docs/status/WBV2-P15-000.md b/docs/status/WBV2-P15-000.md new file mode 100644 index 000000000..13e310bfc --- /dev/null +++ b/docs/status/WBV2-P15-000.md @@ -0,0 +1,9 @@ +# WBV2-P15-000 status + +- task: `WBV2-P15-000`; parent: `WBV2-P14-003`; status: `done` +- candidate: `RENDER.LIGHTING_FIELDS`; source API and Chromium test are present +- inventory carried forward: `6900` total, `6618` pending +- duplicate validation: `forbidden`; representative slice only +- nextTask: `WBV2-P15-001` + +P15 is an authorized continuation that reuses the P14 coverage ledger and validates one source-backed Camera/Light/World behavior batch in Chromium. diff --git a/docs/status/WBV2-P15-001.md b/docs/status/WBV2-P15-001.md new file mode 100644 index 000000000..91c631393 --- /dev/null +++ b/docs/status/WBV2-P15-001.md @@ -0,0 +1,11 @@ +# WBV2-P15-001 status + +- task: `WBV2-P15-001`; parent: `WBV2-P15-000`; status: `done` +- selected capability: `RENDER.LIGHTING_FIELDS`; operations: Camera, Light, World fields +- matched inventory entries: `197`; inventory remains `6900` total, `6618` pending +- behavior hash: `09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53` +- dedupe key binds source API/test hashes; repeated Blender/Chromium runs: `0` +- representative slice: `true`; full-family parity: `false` +- nextTask: `WBV2-P15-002` + +The candidate is selected from the existing parity map and source/test implementations. Only one unique Camera/Light/World behavior batch will be executed; matching inventory entries remain coverage references, not completion claims. diff --git a/docs/status/WBV2-P15-002.md b/docs/status/WBV2-P15-002.md new file mode 100644 index 000000000..cf85be4ef --- /dev/null +++ b/docs/status/WBV2-P15-002.md @@ -0,0 +1,11 @@ +# WBV2-P15-002 status + +- task: `WBV2-P15-002`; parent: `WBV2-P15-001`; status: `done` +- Chromium/WASM Main operations: Camera, Light, World fields +- revisions: `1 -> 10` sequential across edit/undo/redo actions +- malformed camera range: `RENDER_PROPERTY_INVALID`; Main revision preserved +- save/reopen: `EXACT`; deterministic second run: `true` +- representative slice: `true`; full-family parity: `false`; inventory pending: `6618` +- nextTask: `WBV2-P15-003` + +The compiled WebEngine WASM Main now has a hash-bound Chromium receipt for bounded Camera/Light/World field edits. The receipt covers only the selected behavior hash and does not close the remaining lighting/render inventory. diff --git a/docs/status/WBV2-P15-003.md b/docs/status/WBV2-P15-003.md new file mode 100644 index 000000000..83e937b2e --- /dev/null +++ b/docs/status/WBV2-P15-003.md @@ -0,0 +1,10 @@ +# WBV2-P15-003 status + +- task: `WBV2-P15-003`; parent: `WBV2-P15-002`; status: `done` +- new engine-bound claim: `RENDER.LIGHTING_FIELDS`; representative entries: `197`; full-family parity: `false` +- total engine-bound feature claims: `9`; inventory: `6900` total, `6618` pending, claimed complete: `0` +- unique behavior runs: `2`; repeated Blender/Chromium validation: `0`; duplicate validation avoided: `true` +- provenance epoch: `2`; release: `AUTHORIZED_REBASELINE_ONLY`; fullHistoricalReproduction: `false` +- nextTask: `NONE` + +The Lighting/Camera/World slice is now a hash-bound Chromium/WASM Main feature claim. The 197 matched inventory entries are coverage references only; remaining lighting/render behaviors require unique behavior evidence. diff --git a/docs/tasks/WBV2-P15-000.md b/docs/tasks/WBV2-P15-000.md new file mode 100644 index 000000000..74ae46a78 --- /dev/null +++ b/docs/tasks/WBV2-P15-000.md @@ -0,0 +1,24 @@ +# WBV2-P15-000: lighting capability continuation root + +- task: WBV2-P15-000 +- parent: WBV2-P14-003 +- status: done +- gap: workflow:authorize_lighting_capability_continuation +- ownerFamily: PROGRAM +- targetImplementationClass: LOCAL_BOUNDED + +## 目标 + +Authorize a source-backed Lighting/Camera/World continuation. P15 reuses the 6900-entry coverage ledger and runs only one representative Chromium production slice for fields already exposed by the compiled WebEngine API. + +## 验收 + +- `node tools/web/generate-wbv2-lights-root.mjs` +- `node tools/web/check-execution-control-plane.mjs` +- `node tools/web/check-v2-task-index.mjs` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P15-000/` +- Manifest: `tests/golden/WBV2-P15-000/manifest.json` +- Rollback: restore P14-003 as queue parent without rewriting P14 evidence. diff --git a/docs/tasks/WBV2-P15-001.md b/docs/tasks/WBV2-P15-001.md new file mode 100644 index 000000000..84d035ce0 --- /dev/null +++ b/docs/tasks/WBV2-P15-001.md @@ -0,0 +1,34 @@ +# WBV2-P15-001: select_lighting_capability_batch + +- task: WBV2-P15-001 +- parent: WBV2-P15-000 +- status: in_progress +- gap: capability:RENDER.LIGHTING_FIELDS +- ownerFamily: PARITY +- targetImplementationClass: LOCAL_BOUNDED + +## 目标 + +Select one deterministic Camera, Light, and World field behavior batch from the existing source API and Chromium test. + +## 输入与范围 + +- Focused source: `blender-5.2.0/source/blender/web_engine/web_engine_api.cpp` +- Existing production test: `web/tests/e2e/lighting-field-roundtrip.spec.ts` +- Inventory: `tests/golden/WBV2-P0-002/parity-map.json` +- Production entrypoint: `node tools/web/generate-wbv2-lighting-selection.mjs --write` + +## 验收 + +- source API and Chromium test hashes are bound +- one behavior hash covers camera/light/world fields +- representative slice is not promoted to full-family parity +- malformed, hash-drift, unsupported, or false-completion input keeps in_progress +- `node tools/web/check-task-context.mjs --task WBV2-P15-001 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P15-001/` +- Status: `docs/status/WBV2-P15-001.md` +- Manifest: `tests/golden/WBV2-P15-001/manifest.json` +- Rollback: restore P15-000 as queue parent. diff --git a/docs/tasks/WBV2-P15-002.md b/docs/tasks/WBV2-P15-002.md new file mode 100644 index 000000000..3a0858c69 --- /dev/null +++ b/docs/tasks/WBV2-P15-002.md @@ -0,0 +1,34 @@ +# WBV2-P15-002: lighting_fields_engine_receipt + +- task: WBV2-P15-002 +- parent: WBV2-P15-001 +- status: in_progress +- gap: capability:RENDER.LIGHTING_FIELDS +- ownerFamily: RENDER +- targetImplementationClass: LOCAL_EXACT + +## 目标 + +Bind Camera, Light, and World edits, undo/redo, and exact save/reopen to the compiled WASM Main in Chromium. + +## 输入与范围 + +- Focused source: `tests/golden/WBV2-P15-001/lighting-selection-report.json` +- Production test: `web/tests/e2e/wbv2-lighting-fields-production.spec.ts` +- Production entrypoint: `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-lighting-fields-production.spec.ts` + +## 验收 + +- camera/light/world fields match the bounded expected values +- undo/redo revisions are sequential +- save/reopen is exact +- malformed values fail closed without Main mutation +- Chromium is the only browser +- `node tools/web/check-task-context.mjs --task WBV2-P15-002 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P15-002/` +- Status: `docs/status/WBV2-P15-002.md` +- Manifest: `tests/golden/WBV2-P15-002/manifest.json` +- Rollback: restore P15-001 as queue parent. diff --git a/docs/tasks/WBV2-P15-003.md b/docs/tasks/WBV2-P15-003.md new file mode 100644 index 000000000..ced6f80e0 --- /dev/null +++ b/docs/tasks/WBV2-P15-003.md @@ -0,0 +1,34 @@ +# WBV2-P15-003: close_lighting_capability_gate + +- task: WBV2-P15-003 +- parent: WBV2-P15-002 +- status: in_progress +- gap: workflow:close_lighting_capability_gate +- ownerFamily: RELEASE +- targetImplementationClass: LOCAL_BOUNDED + +## 目标 + +Close the Lighting capability gate while preserving partial-family and 6900-entry limitations. + +## 输入与范围 + +- Focused receipt: `tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json` +- Coverage matrix: `tests/golden/WBV2-P14-002/capability-evidence-matrix.json` +- Production entrypoint: `node tools/web/generate-wbv2-lighting-gate.mjs --write` + +## 验收 + +- only the tested lighting slice is claimed +- pending inventory remains 6618 +- duplicate validation remains zero +- historical reproduction remains false +- malformed, hash-drift, or unsupported evidence keeps the gate in_progress +- `node tools/web/check-task-context.mjs --task WBV2-P15-003 --write` + +## 交付与回滚 + +- Reports: `tests/golden/WBV2-P15-003/` +- Status: `docs/status/WBV2-P15-003.md` +- Manifest: `tests/golden/WBV2-P15-003/manifest.json` +- Rollback: restore P15-002 as queue parent. diff --git a/nextTask.md b/nextTask.md index fcb0f4449..b34bf233c 100644 --- a/nextTask.md +++ b/nextTask.md @@ -240,12 +240,12 @@ Recorded: 2026-08-22 America/New_York | Field | Value | | --- | --- | -| Current task when this file was written | `WBV2-P14-003` | +| Current task when this file was written | `WBV2-P15-003` | | Current task state | `done` | -| Parent manifest | `tests/golden/WBV2-P14-002/manifest.json` | -| Current task card | `docs/tasks/WBV2-P14-003.md` | +| Parent manifest | `tests/golden/WBV2-P15-002/manifest.json` | +| Current task card | `docs/tasks/WBV2-P15-003.md` | | Current task-context nextTask | `NONE` | -| Focused command | `node tools/web/generate-wbv2-inventory-coverage-gate.mjs --write` | +| Focused command | `node tools/web/generate-wbv2-lighting-gate.mjs --write` | The snapshot is informational and may become stale. On every resume, the queue, parent manifest, and fresh `print-task-context` output win. Never infer a task diff --git a/tests/golden/WBV2-P15-000/lights-root-report.json b/tests/golden/WBV2-P15-000/lights-root-report.json new file mode 100644 index 000000000..35f4bd3d0 --- /dev/null +++ b/tests/golden/WBV2-P15-000/lights-root-report.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-000", + "operation": "AUTHORIZE_LIGHTING_CAPABILITY_CONTINUATION", + "status": "PASS", + "parent": { + "task": "WBV2-P14-003", + "manifest": "tests/golden/WBV2-P14-003/manifest.json", + "manifestSha256": "a79051e09719cb4b73f98a895f47d6c093081b00c929e8f322672d957ccd4367", + "report": "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json", + "reportSha256": "5ef8bec5dfe603452b04629709ca0e7f11b2ce4cec4a96af25f6c4b7634b64bd", + "previousDecision": "COVERAGE_ACCOUNTED_WITH_LIMITED_DECLARATION" + }, + "continuation": { + "root": "WBV2-P15-000", + "firstTask": "WBV2-P15-001", + "plannedTasks": 4, + "candidate": "RENDER.LIGHTING_FIELDS", + "sourceApi": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "chromiumTest": "web/tests/e2e/lighting-field-roundtrip.spec.ts", + "browser": "chromium", + "inventoryTotal": 6900, + "inventoryPending": 6618, + "noRepeatedExecution": true + }, + "policy": { + "p14EvidencePreserved": true, + "sourceHistoryReadOnly": true, + "representativeSliceOnly": true, + "duplicateValidationAvoided": true, + "authorizedRebaselineOnly": true, + "fullHistoricalReproduction": false + }, + "nextTask": "WBV2-P15-001" +} diff --git a/tests/golden/WBV2-P15-000/lights-task-plan.json b/tests/golden/WBV2-P15-000/lights-task-plan.json new file mode 100644 index 000000000..6db57af42 --- /dev/null +++ b/tests/golden/WBV2-P15-000/lights-task-plan.json @@ -0,0 +1,146 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_LIGHTING_EPOCH_1", + "status": "ACTIVE_LIGHTING_QUEUE", + "authority": "queue_reactivated_after_p14_coverage_gate", + "sourcePlan": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "reusePolicy": "source_hash_and_behavior_hash_deduplication" + }, + "parentCoverage": { + "manifest": "tests/golden/WBV2-P14-003/manifest.json", + "report": "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json", + "inventoryTotal": 6900, + "inventoryPending": 6618, + "duplicateValidationAvoided": true + }, + "tasks": [ + { + "id": "WBV2-P15-000", + "phase": "P15", + "title": "authorize_lighting_capability_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P14-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-governance", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-000.md", + "behavior": "Authorize a source-backed Lighting/Camera/World capability slice without reopening completed batches.", + "outputs": [ + "continuation root", + "candidate scope", + "hash boundary" + ], + "acceptance": [ + "P14 coverage remains hash-bound", + "source command and Chromium test exist", + "one production task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P15-001", + "phase": "P15", + "title": "select_lighting_capability_batch", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P15-000" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-selection", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-001.md", + "behavior": "Select one deterministic Lighting/Camera/World behavior batch from existing source and tests.", + "outputs": [ + "candidate report", + "behavior hash", + "dedupe key" + ], + "acceptance": [ + "source API is present", + "Chromium test is present", + "candidate remains representative rather than full-family completion" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-002", + "phase": "P15", + "title": "lighting_fields_engine_receipt", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P15-001" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p15-lighting", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-002.md", + "behavior": "Bind Camera, Light, and World field edits, undo/redo, and exact save/reopen to compiled WASM Main in Chromium.", + "outputs": [ + "lighting production report", + "lighting receipt", + "manifest" + ], + "acceptance": [ + "camera/light/world fields match", + "undo/redo revisions are sequential", + "save/reopen is exact", + "malformed values fail closed" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-003", + "phase": "P15", + "title": "close_lighting_capability_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P15-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P15-003.md", + "behavior": "Close the Lighting capability gate while preserving partial-family and 6900-entry limitations.", + "outputs": [ + "lighting gate", + "limited declaration", + "manifest" + ], + "acceptance": [ + "only the tested slice is claimed", + "inventory remainder remains 6618", + "no repeated validation or historical over-claim" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ] +} diff --git a/tests/golden/WBV2-P15-000/manifest.json b/tests/golden/WBV2-P15-000/manifest.json new file mode 100644 index 000000000..19d705897 --- /dev/null +++ b/tests/golden/WBV2-P15-000/manifest.json @@ -0,0 +1,60 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-000", + "parentTask": "WBV2-P14-003", + "operation": "AUTHORIZE_LIGHTING_CAPABILITY_CONTINUATION", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "READ_ONLY_LIGHTING_CONTINUATION_ROOT", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P14-003/manifest.json", + "sha256": "a79051e09719cb4b73f98a895f47d6c093081b00c929e8f322672d957ccd4367" + }, + "parentReport": { + "path": "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json", + "sha256": "5ef8bec5dfe603452b04629709ca0e7f11b2ce4cec4a96af25f6c4b7634b64bd" + }, + "sourceMap": { + "path": "tests/golden/WBV2-P0-002/parity-map.json", + "sha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8" + }, + "sourceApi": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8" + }, + "sourceTest": { + "path": "web/tests/e2e/lighting-field-roundtrip.spec.ts", + "sha256": "9f75c7b88c70ab42c6c418b0056dcffcab3b8851003258891902db9615fcfe67" + }, + "plan": { + "path": "tests/golden/WBV2-P15-000/lights-task-plan.json", + "sha256": "aa90622e43a5f2cef2c5f75128ffda83e1800e14faa59450aaf3af11fcdc8012" + }, + "report": { + "path": "tests/golden/WBV2-P15-000/lights-root-report.json", + "sha256": "6bdbdc3e0e7d8dcb6b3ff9438f21015e1f60c677974c1a922c3f784cffb0f083" + }, + "rootCard": { + "path": "docs/tasks/WBV2-P15-000.md", + "sha256": "b880447b9bcacd682370c5e38966e299b3964aae2cf370638cdb4aecdb56f8f6" + }, + "rootStatus": { + "path": "docs/status/WBV2-P15-000.md", + "sha256": "e34cfa33d077ca01ce0dde82952d9b3de9fcebf50d38b7564169ebce9efa65c1" + } + }, + "assertions": { + "p14EvidencePreserved": true, + "sourceApiBound": true, + "chromiumTestBound": true, + "inventoryTotal": 6900, + "inventoryPending": 6618, + "duplicateValidationAvoided": true, + "representativeSliceOnly": true, + "authorizedRebaselineOnly": true, + "fullHistoricalReproduction": false + }, + "nextTask": "WBV2-P15-001" +} diff --git a/tests/golden/WBV2-P15-001/lighting-candidate-set.json b/tests/golden/WBV2-P15-001/lighting-candidate-set.json new file mode 100644 index 000000000..a109362d8 --- /dev/null +++ b/tests/golden/WBV2-P15-001/lighting-candidate-set.json @@ -0,0 +1,2233 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-001", + "operation": "LIGHTING_CAPABILITY_CANDIDATE_SELECTION", + "status": "READY", + "source": { + "inventory": "tests/golden/WBV2-P0-002/parity-map.json", + "inventorySha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8", + "api": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "apiSha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8", + "test": "web/tests/e2e/lighting-field-roundtrip.spec.ts", + "testSha256": "9f75c7b88c70ab42c6c418b0056dcffcab3b8851003258891902db9615fcfe67", + "golden": "tests/golden/M11-02/lighting-field-roundtrip.json", + "goldenSha256": "ac6d84c0099b12cf6c96df2dbbb4281e3308c36f0bda49c92d7548e58ccc286e", + "strategy": "tests/golden/WBV2-P14-003/batch-execution-strategy.json", + "strategySha256": "1d3cf10b97e2ecb170a744ca6687601a64ad7ede1cc82dcbbc80b4291637122f" + }, + "candidate": { + "capabilityId": "RENDER.LIGHTING_FIELDS", + "representativeBehavior": { + "capability": "RENDER.LIGHTING_FIELDS", + "operations": [ + "setCameraProperties", + "setLightProperties", + "setWorldProperties" + ], + "positive": [ + "field-edit", + "undo", + "redo", + "save-reopen" + ], + "negative": [ + "invalid-camera-range", + "missing-data-id" + ], + "browser": "chromium", + "engine": "compiled-WASM-WebEngine-Main", + "sourceGolden": "M11-02/lighting-field-roundtrip.json" + }, + "behaviorHash": "09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53", + "dedupeKey": "RENDER.LIGHTING_FIELDS|09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53|8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8|9f75c7b88c70ab42c6c418b0056dcffcab3b8851003258891902db9615fcfe67", + "sourceBacked": true, + "chromiumProductionReady": true, + "fullFamilyParity": false + }, + "inventory": { + "matchedEntries": 197, + "counts": { + "pending": 194, + "completed": 3 + }, + "total": 6900, + "pending": 6618, + "remainderExplicit": true + }, + "entries": [ + { + "id": "constraint:CAMERA_SOLVER", + "kind": "constraint", + "capabilityId": "CAP-RIG-ANIMATION", + "family": "RIG_ANIMATION", + "ownerFamily": "CONSTRAINT", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "datablock:Camera", + "kind": "datablock", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "RNA_DATABLOCK", + "sourceTask": "M15-01A", + "legacyState": "completed", + "state": "completed", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "datablock:Light", + "kind": "datablock", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "RNA_DATABLOCK", + "sourceTask": "M15-01A", + "legacyState": "completed", + "state": "completed", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "datablock:World", + "kind": "datablock", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "RNA_DATABLOCK", + "sourceTask": "M15-01A", + "legacyState": "completed", + "state": "completed", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Geometry:GeometryNodeCameraInfo", + "kind": "node", + "capabilityId": "CAP-NODES-GRAPH", + "family": "NODES_GRAPH", + "ownerFamily": "GEOMETRY_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Geometry:GeometryNodeInputActiveCamera", + "kind": "node", + "capabilityId": "CAP-NODES-GRAPH", + "family": "NODES_GRAPH", + "ownerFamily": "GEOMETRY_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeAddShader", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeAmbientOcclusion", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeAttribute", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBackground", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBevel", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBlackbody", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBrightContrast", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfAnisotropic", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfDiffuse", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfGlass", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfHair", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfHairPrincipled", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfMetallic", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfPrincipled", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfRayPortal", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfRefraction", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfSheen", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfToon", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfTranslucent", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBsdfTransparent", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeBump", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeCameraData", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeClamp", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeCombineColor", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeCombineXYZ", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeDisplacement", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeEeveeSpecular", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeEmission", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeFloatCurve", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeFresnel", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeGamma", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeGroup", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeHairInfo", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeHoldout", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeHueSaturation", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeInvert", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeLayerWeight", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeLightFalloff", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeLightPath", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeMapRange", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeMapping", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeMath", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeMix", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeMixRGB", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeMixShader", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeNewGeometry", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeNormal", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeNormalMap", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeObjectInfo", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeOutputAOV", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeOutputLight", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeOutputLineStyle", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeOutputMaterial", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeOutputWorld", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeParticleInfo", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodePointInfo", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeRGB", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeRGBCurve", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeRGBToBW", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeRadialTiling", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeRaycast", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeScript", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeSeparateColor", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeSeparateXYZ", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeShaderToRGB", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeSqueeze", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeSubsurfaceScattering", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTangent", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexBrick", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexChecker", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexCoord", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexEnvironment", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexGabor", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexGradient", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexIES", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexImage", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexMagic", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexNoise", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexSky", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexVoronoi", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexWave", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeTexWhiteNoise", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeUVAlongStroke", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeUVMap", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeValToRGB", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeValue", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVectorCurve", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVectorDisplacement", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVectorMath", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVectorRotate", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVectorTransform", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVertexColor", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVolumeAbsorption", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVolumeCoefficients", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVolumeInfo", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVolumePrincipled", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeVolumeScatter", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeWavelength", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "node:Shader:ShaderNodeWireframe", + "kind": "node", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "SHADER_NODE", + "sourceTask": "M15-01C", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:camera.preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:camera.safe_areas_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:clip.camera_preset_add", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:clip.solve_camera", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:cycles.denoise_animation", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:cycles.merge_images", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:cycles.use_shading_nodes", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:file.highlight", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:geometry.color_attribute_render_set", + "kind": "operator", + "capabilityId": "CAP-NODES-GRAPH", + "family": "NODES_GRAPH", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:image.add_render_slot", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:image.clear_render_border", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:image.clear_render_slot", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:image.cycle_render_slot", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:image.remove_render_slot", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:image.render_border", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:marker.camera_bind", + "kind": "operator", + "capabilityId": "CAP-RIG-ANIMATION", + "family": "RIG_ANIMATION", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:material.copy", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:material.new", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:material.paste", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:node.render_changed", + "kind": "operator", + "capabilityId": "CAP-NODES-GRAPH", + "family": "NODES_GRAPH", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.camera_add", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.camera_custom_update", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.delete_fix_to_camera_keys", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.fix_to_camera", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.hide_render_clear_all", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.isolate_type_render", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_add", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_blocker_collection_new", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_blockers_link", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_blockers_select", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_receiver_collection_new", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_receivers_link", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_receivers_select", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.light_linking_unlink_from_collection", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.lightprobe_add", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.lightprobe_cache_bake", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.lightprobe_cache_free", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:object.select_camera", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:outliner.collection_disable_render", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:outliner.collection_enable_render", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:outliner.highlight_update", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:preferences.studiolight_copy_settings", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:preferences.studiolight_install", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:preferences.studiolight_new", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:preferences.studiolight_uninstall", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.clear_texture_cache", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.color_management_white_balance_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.cycles_integrator_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.cycles_performance_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.cycles_sampling_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.cycles_viewport_sampling_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.eevee_raytracing_preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.generate_texture_cache", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.opengl", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.play_rendered_anim", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.preset_add", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.render", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.shutter_curve_preset", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.swap_dimensions", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.view_cancel", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:render.view_show", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:rigidbody.world_add", + "kind": "operator", + "capabilityId": "CAP-SIMULATION", + "family": "SIMULATION", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:rigidbody.world_remove", + "kind": "operator", + "capabilityId": "CAP-SIMULATION", + "family": "SIMULATION", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:scene.render_view_add", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:scene.render_view_remove", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:scene.view_layer_add_lightgroup", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:scene.view_layer_add_used_lightgroups", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:scene.view_layer_remove_lightgroup", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:scene.view_layer_remove_unused_lightgroups", + "kind": "operator", + "capabilityId": "CAP-OBJECT-OPERATIONS", + "family": "OBJECT_OPERATIONS", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:sequencer.rendersize", + "kind": "operator", + "capabilityId": "CAP-MEDIA-IO", + "family": "MEDIA_IO", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:uv.lightmap_pack", + "kind": "operator", + "capabilityId": "CAP-OTHER-OPERATOR", + "family": "OTHER_OPERATOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.camera_background_image_add", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.camera_background_image_remove", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.camera_to_view", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.camera_to_view_selected", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.clear_render_border", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.drop_world", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.object_as_camera", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.render_border", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.view_camera", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.view_center_camera", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:view3d.zoom_camera_1_to_1", + "kind": "operator", + "capabilityId": "CAP-UI-EDITOR", + "family": "UI_EDITOR", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:world.convert_volume_to_mesh", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "operator:world.new", + "kind": "operator", + "capabilityId": "CAP-MATERIAL-RENDER", + "family": "MATERIAL_RENDER", + "ownerFamily": "OPERATOR", + "sourceTask": "M15-01B", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "physics:RigidBodyWorld", + "kind": "physics", + "capabilityId": "CAP-SIMULATION", + "family": "SIMULATION", + "ownerFamily": "PHYSICS", + "sourceTask": "M15-01D", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Main:BlendDataCameras", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Main", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Main:BlendDataLights", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Main", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Main:BlendDataWorlds", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Main", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Scene:Camera", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Scene", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Scene:Light", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Scene", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Scene:RenderSettings", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Scene", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + }, + { + "id": "rna:Scene:World", + "kind": "rna", + "capabilityId": "CAP-CORE-SCENE-GRAPH", + "family": "CORE_SCENE_GRAPH", + "ownerFamily": "Scene", + "sourceTask": "M15-01F", + "legacyState": "pending", + "state": "pending", + "targetImplementationClass": "LOCAL_EXACT" + } + ], + "policy": { + "sourceHistoryReadOnly": true, + "representativeSliceOnly": true, + "noRepeatedExecution": true, + "duplicateValidationAvoided": true, + "fullHistoricalReproduction": false + } +} diff --git a/tests/golden/WBV2-P15-001/lighting-selection-report.json b/tests/golden/WBV2-P15-001/lighting-selection-report.json new file mode 100644 index 000000000..a860f88ad --- /dev/null +++ b/tests/golden/WBV2-P15-001/lighting-selection-report.json @@ -0,0 +1,66 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-001", + "operation": "SELECT_LIGHTING_CAPABILITY_BATCH", + "status": "PASS", + "candidate": { + "capabilityId": "RENDER.LIGHTING_FIELDS", + "representativeBehavior": { + "capability": "RENDER.LIGHTING_FIELDS", + "operations": [ + "setCameraProperties", + "setLightProperties", + "setWorldProperties" + ], + "positive": [ + "field-edit", + "undo", + "redo", + "save-reopen" + ], + "negative": [ + "invalid-camera-range", + "missing-data-id" + ], + "browser": "chromium", + "engine": "compiled-WASM-WebEngine-Main", + "sourceGolden": "M11-02/lighting-field-roundtrip.json" + }, + "behaviorHash": "09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53", + "dedupeKey": "RENDER.LIGHTING_FIELDS|09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53|8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8|9f75c7b88c70ab42c6c418b0056dcffcab3b8851003258891902db9615fcfe67", + "sourceBacked": true, + "chromiumProductionReady": true, + "fullFamilyParity": false + }, + "inventory": { + "matchedEntries": 197, + "counts": { + "pending": 194, + "completed": 3 + }, + "total": 6900, + "pending": 6618, + "remainderExplicit": true + }, + "source": { + "inventory": "tests/golden/WBV2-P0-002/parity-map.json", + "inventorySha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8", + "api": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "apiSha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8", + "test": "web/tests/e2e/lighting-field-roundtrip.spec.ts", + "testSha256": "9f75c7b88c70ab42c6c418b0056dcffcab3b8851003258891902db9615fcfe67", + "golden": "tests/golden/M11-02/lighting-field-roundtrip.json", + "goldenSha256": "ac6d84c0099b12cf6c96df2dbbb4281e3308c36f0bda49c92d7548e58ccc286e", + "strategy": "tests/golden/WBV2-P14-003/batch-execution-strategy.json", + "strategySha256": "1d3cf10b97e2ecb170a744ca6687601a64ad7ede1cc82dcbbc80b4291637122f" + }, + "matchedEntryDigest": "0e812a79bd48ce9cfcb2e973e41333346d1c40157be0f8ba824ac2f367b755e3", + "efficiency": { + "oneSourceScan": true, + "existingStrategyReused": true, + "repeatedBlenderRuns": 0, + "repeatedChromiumRuns": 0, + "duplicateValidationAvoided": true + }, + "nextTask": "WBV2-P15-002" +} diff --git a/tests/golden/WBV2-P15-001/lights-task-plan.json b/tests/golden/WBV2-P15-001/lights-task-plan.json new file mode 100644 index 000000000..116ba863c --- /dev/null +++ b/tests/golden/WBV2-P15-001/lights-task-plan.json @@ -0,0 +1,150 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_LIGHTING_EPOCH_1", + "status": "ACTIVE_LIGHTING_QUEUE", + "authority": "queue_reactivated_after_p14_coverage_gate", + "sourcePlan": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "reusePolicy": "source_hash_and_behavior_hash_deduplication" + }, + "parentCoverage": { + "manifest": "tests/golden/WBV2-P14-003/manifest.json", + "report": "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json", + "inventoryTotal": 6900, + "inventoryPending": 6618, + "duplicateValidationAvoided": true + }, + "tasks": [ + { + "id": "WBV2-P15-000", + "phase": "P15", + "title": "authorize_lighting_capability_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P14-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-governance", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-000.md", + "behavior": "Authorize a source-backed Lighting/Camera/World capability slice without reopening completed batches.", + "outputs": [ + "continuation root", + "candidate scope", + "hash boundary" + ], + "acceptance": [ + "P14 coverage remains hash-bound", + "source command and Chromium test exist", + "one production task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P15-001", + "phase": "P15", + "title": "select_lighting_capability_batch", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P15-000" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-selection", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-001.md", + "behavior": "Select one deterministic Lighting/Camera/World behavior batch from existing source and tests.", + "outputs": [ + "candidate report", + "behavior hash", + "dedupe key" + ], + "acceptance": [ + "source API is present", + "Chromium test is present", + "candidate remains representative rather than full-family completion" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-002", + "phase": "P15", + "title": "lighting_fields_engine_receipt", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P15-001" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p15-lighting", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-002.md", + "behavior": "Bind Camera, Light, and World field edits, undo/redo, and exact save/reopen to compiled WASM Main in Chromium.", + "outputs": [ + "lighting production report", + "lighting receipt", + "manifest" + ], + "acceptance": [ + "camera/light/world fields match", + "undo/redo revisions are sequential", + "save/reopen is exact", + "malformed values fail closed" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-003", + "phase": "P15", + "title": "close_lighting_capability_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P15-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P15-003.md", + "behavior": "Close the Lighting capability gate while preserving partial-family and 6900-entry limitations.", + "outputs": [ + "lighting gate", + "limited declaration", + "manifest" + ], + "acceptance": [ + "only the tested slice is claimed", + "inventory remainder remains 6618", + "no repeated validation or historical over-claim" + ], + "status": "planned", + "ready": false, + "queueMutationAllowed": false + } + ], + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P15-000/lights-task-plan.json", + "sha256": "aa90622e43a5f2cef2c5f75128ffda83e1800e14faa59450aaf3af11fcdc8012" + } +} diff --git a/tests/golden/WBV2-P15-001/manifest.json b/tests/golden/WBV2-P15-001/manifest.json new file mode 100644 index 000000000..5ab1a8e7a --- /dev/null +++ b/tests/golden/WBV2-P15-001/manifest.json @@ -0,0 +1,76 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-001", + "parentTask": "WBV2-P15-000", + "operation": "SELECT_LIGHTING_CAPABILITY_BATCH", + "status": "done", + "enablingTask": true, + "parityStateChange": false, + "runtime": "READ_ONLY_SOURCE_CANDIDATE_SELECTION", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P15-000/manifest.json", + "sha256": "e258bf87739c5396a122e7aa08c128b4c6208e2259f8a186845469dde161dfe6" + }, + "inventory": { + "path": "tests/golden/WBV2-P0-002/parity-map.json", + "sha256": "a60a77cae000941a953d55adbf93d8f6e275533891713d6eae993f60faed94e8" + }, + "strategy": { + "path": "tests/golden/WBV2-P14-003/batch-execution-strategy.json", + "sha256": "1d3cf10b97e2ecb170a744ca6687601a64ad7ede1cc82dcbbc80b4291637122f" + }, + "sourceApi": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8" + }, + "sourceTest": { + "path": "web/tests/e2e/lighting-field-roundtrip.spec.ts", + "sha256": "9f75c7b88c70ab42c6c418b0056dcffcab3b8851003258891902db9615fcfe67" + }, + "sourceGolden": { + "path": "tests/golden/M11-02/lighting-field-roundtrip.json", + "sha256": "ac6d84c0099b12cf6c96df2dbbb4281e3308c36f0bda49c92d7548e58ccc286e" + }, + "candidate": { + "path": "tests/golden/WBV2-P15-001/lighting-candidate-set.json", + "sha256": "8b6c1d0641ace02c128518feb6c4c6893f4a88b01015972232a91b186e40102d" + }, + "report": { + "path": "tests/golden/WBV2-P15-001/lighting-selection-report.json", + "sha256": "eeb14c189794036b39e7b569b8d89ef231a7c4631f7bf16e0b0bf0c21896d8bd" + }, + "generator": { + "path": "tools/web/generate-wbv2-lighting-selection.mjs", + "sha256": "df36373c4c2fa56f1f272dfd130411025b61f8cc7d31734abe3d47454e91352f" + }, + "status": { + "path": "docs/status/WBV2-P15-001.md", + "sha256": "d92b8b48a3baebdb313c6a6bf244559b850ea4181cca52ebc4b166e73c076f14" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P15-001/lights-task-plan.json", + "sha256": "bd9e53c6c35e0fe436b5b7e1f1e0d9a2cf67d20e2cbda418cddf5ad2223a32e7" + }, + "taskContext": { + "path": "tests/golden/WBV2-P15-001/task-context.json", + "sha256": "9c092966442fde3c7c4b7002f3556216cd3a20e9324735f7d4d6f4da6adc2c6c" + } + }, + "assertions": { + "capability": "RENDER.LIGHTING_FIELDS", + "matchedInventoryEntries": 197, + "inventoryTotal": 6900, + "inventoryPending": 6618, + "sourceApiBound": true, + "chromiumTestBound": true, + "representativeSliceOnly": true, + "fullFamilyParity": false, + "repeatedBlenderRuns": 0, + "repeatedChromiumRuns": 0, + "duplicateValidationAvoided": true, + "deterministic": true, + "historicalReproduction": false + }, + "nextTask": "WBV2-P15-002" +} diff --git a/tests/golden/WBV2-P15-001/task-context.json b/tests/golden/WBV2-P15-001/task-context.json new file mode 100644 index 000000000..f0800b42c --- /dev/null +++ b/tests/golden/WBV2-P15-001/task-context.json @@ -0,0 +1,172 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-001", + "parentTask": "WBV2-P15-000", + "status": "in_progress", + "goal": "Select one deterministic Camera, Light, and World field behavior batch from the existing source API and Chromium test.", + "scope": { + "gap": "capability:RENDER.LIGHTING_FIELDS", + "ownerFamily": "PARITY", + "implementationClass": "LOCAL_BOUNDED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P15-001 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 3249, + "contextRemainingTokens": 812 + }, + "source": { + "bytes": 6655, + "tokens": 1664 + }, + "selected": [], + "excluded": [ + { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "bytes": 126797, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "web/tests/e2e/lighting-field-roundtrip.spec.ts", + "bytes": 8390, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P0-002/parity-map.json", + "bytes": 5053386, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P15-001/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P15-001.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P15-001/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "source API is present", + "Chromium test is present", + "candidate remains representative rather than full-family completion" + ], + "nextTask": "WBV2-P15-002", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P15-001.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P15-000/manifest.json", + "parentStatus": "docs/status/WBV2-P15-000.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P15-001.md", + "tests/golden/WBV2-P15-000/manifest.json", + "docs/status/WBV2-P15-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-P15-000", + "parentTask": "WBV2-P14-003", + "status": "done", + "nextTask": "WBV2-P15-001", + "artifactCount": 9 + }, + "statusSummary": [ + "# WBV2-P15-000 status", + "- task: `WBV2-P15-000`; parent: `WBV2-P14-003`; status: `done`", + "- candidate: `RENDER.LIGHTING_FIELDS`; source API and Chromium test are present", + "- inventory carried forward: `6900` total, `6618` pending", + "- duplicate validation: `forbidden`; representative slice only", + "- nextTask: `WBV2-P15-001`", + "P15 is an authorized continuation that reuses the P14 coverage ledger and validates one source-backed Camera/Light/World behavior batch in Chromium." + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1200, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 36, + "taskTokens": 300 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P15-001.md", + "bytes": 1200, + "lines": 36, + "tokens": 300 + }, + { + "path": "tests/golden/WBV2-P15-000/manifest.json", + "bytes": 2188, + "lines": 61, + "tokens": 547 + }, + { + "path": "docs/status/WBV2-P15-000.md", + "bytes": 464, + "lines": 10, + "tokens": 116 + } + ], + "sourceTokens": 1664, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1664, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2688, + "serializedContextTokens": 608, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P15-002/lighting-fields-production.json b/tests/golden/WBV2-P15-002/lighting-fields-production.json new file mode 100644 index 000000000..f1b9739da --- /dev/null +++ b/tests/golden/WBV2-P15-002/lighting-fields-production.json @@ -0,0 +1,97 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-002", + "operation": "LIGHTING_FIELDS_ENGINE_CHROMIUM", + "queueMutation": false, + "browser": "chromium", + "sourceSha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73", + "beforeRevision": 1, + "revisions": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "malformed": { + "code": "RENDER_PROPERTY_INVALID", + "message": "Camera far clip must exceed near clip" + }, + "malformedRevisionPreserved": true, + "camera": { + "depthOfField": { + "apertureBlades": 7, + "apertureFStop": 1.7999999523162842, + "apertureRatio": 1.2000000476837158, + "apertureRotation": 0.25, + "enabled": true, + "focusDistance": 4.5, + "focusObjectId": null + }, + "far": 500, + "fisheyeFov": 3.1415927410125732, + "id": "camera:Camera.001", + "lensMm": 35, + "name": "Camera.001", + "near": 0.20000000298023224, + "orthoScale": 8, + "panoramaType": 2, + "projection": "PERSPECTIVE", + "sensorFit": 2, + "sensorHeightMm": 18, + "sensorWidthMm": 32, + "shift": [ + 0.10000000149011612, + -0.20000000298023224 + ] + }, + "light": { + "areaShape": 4, + "areaSize": 3, + "areaSizeY": 2, + "areaSpread": 2.4000000953674316, + "castsShadow": false, + "color": [ + 0.25, + 0.5, + 0.75 + ], + "energy": 400, + "exposure": 1, + "id": "light:Area", + "lightType": 4, + "name": "Area", + "radius": 0.30000001192092896, + "spotAngle": 1.100000023841858, + "spotBlend": 0.25, + "sunAngle": 0.10000000149011612, + "temperature": 5000, + "useTemperature": true + }, + "world": { + "backgroundVisible": true, + "color": [ + 0.10000000149011612, + 0.20000000298023224, + 0.30000001192092896 + ], + "exposure": 0.5, + "id": "world:World", + "mist": { + "depth": 50, + "enabled": true, + "height": 3, + "intensity": 0.20000000298023224, + "start": 2, + "type": "LINEAR" + }, + "name": "World" + }, + "reopenedRevision": 1, + "savedSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +} diff --git a/tests/golden/WBV2-P15-002/lighting-fields-production.second.json b/tests/golden/WBV2-P15-002/lighting-fields-production.second.json new file mode 100644 index 000000000..f1b9739da --- /dev/null +++ b/tests/golden/WBV2-P15-002/lighting-fields-production.second.json @@ -0,0 +1,97 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-002", + "operation": "LIGHTING_FIELDS_ENGINE_CHROMIUM", + "queueMutation": false, + "browser": "chromium", + "sourceSha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73", + "beforeRevision": 1, + "revisions": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "malformed": { + "code": "RENDER_PROPERTY_INVALID", + "message": "Camera far clip must exceed near clip" + }, + "malformedRevisionPreserved": true, + "camera": { + "depthOfField": { + "apertureBlades": 7, + "apertureFStop": 1.7999999523162842, + "apertureRatio": 1.2000000476837158, + "apertureRotation": 0.25, + "enabled": true, + "focusDistance": 4.5, + "focusObjectId": null + }, + "far": 500, + "fisheyeFov": 3.1415927410125732, + "id": "camera:Camera.001", + "lensMm": 35, + "name": "Camera.001", + "near": 0.20000000298023224, + "orthoScale": 8, + "panoramaType": 2, + "projection": "PERSPECTIVE", + "sensorFit": 2, + "sensorHeightMm": 18, + "sensorWidthMm": 32, + "shift": [ + 0.10000000149011612, + -0.20000000298023224 + ] + }, + "light": { + "areaShape": 4, + "areaSize": 3, + "areaSizeY": 2, + "areaSpread": 2.4000000953674316, + "castsShadow": false, + "color": [ + 0.25, + 0.5, + 0.75 + ], + "energy": 400, + "exposure": 1, + "id": "light:Area", + "lightType": 4, + "name": "Area", + "radius": 0.30000001192092896, + "spotAngle": 1.100000023841858, + "spotBlend": 0.25, + "sunAngle": 0.10000000149011612, + "temperature": 5000, + "useTemperature": true + }, + "world": { + "backgroundVisible": true, + "color": [ + 0.10000000149011612, + 0.20000000298023224, + 0.30000001192092896 + ], + "exposure": 0.5, + "id": "world:World", + "mist": { + "depth": 50, + "enabled": true, + "height": 3, + "intensity": 0.20000000298023224, + "start": 2, + "type": "LINEAR" + }, + "name": "World" + }, + "reopenedRevision": 1, + "savedSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" +} diff --git a/tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json b/tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json new file mode 100644 index 000000000..ae19bf75d --- /dev/null +++ b/tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json @@ -0,0 +1,135 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-002", + "operation": "LIGHTING_FIELDS_ENGINE_RECEIPT", + "status": "PASS", + "browser": "chromium", + "queueMutation": false, + "source": { + "task": "WBV2-P15-001", + "manifest": "tests/golden/WBV2-P15-001/manifest.json", + "manifestSha256": "e8f2cf5cd71282abe89c33570309a202c06ef04237e82064356b4c2f86577f60", + "selection": "tests/golden/WBV2-P15-001/lighting-selection-report.json", + "selectionSha256": "eeb14c189794036b39e7b569b8d89ef231a7c4631f7bf16e0b0bf0c21896d8bd", + "fixture": "tests/files/web/basic_scene.blend", + "fixtureSha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73", + "expected": "tests/golden/M11-02/lighting-field-roundtrip.json", + "expectedSha256": "ac6d84c0099b12cf6c96df2dbbb4281e3308c36f0bda49c92d7548e58ccc286e", + "api": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "apiSha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8" + }, + "production": { + "report": "tests/golden/WBV2-P15-002/lighting-fields-production.json", + "reportSha256": "c744d1196d7c779561d00e900d591e05328d99e95579a1b5c7a9df7732255c0c", + "secondReport": "tests/golden/WBV2-P15-002/lighting-fields-production.second.json", + "secondReportSha256": "c744d1196d7c779561d00e900d591e05328d99e95579a1b5c7a9df7732255c0c", + "deterministic": true, + "operations": [ + "setCameraProperties", + "setLightProperties", + "setWorldProperties" + ], + "revisions": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "camera": { + "depthOfField": { + "apertureBlades": 7, + "apertureFStop": 1.7999999523162842, + "apertureRatio": 1.2000000476837158, + "apertureRotation": 0.25, + "enabled": true, + "focusDistance": 4.5, + "focusObjectId": null + }, + "far": 500, + "fisheyeFov": 3.1415927410125732, + "id": "camera:Camera.001", + "lensMm": 35, + "name": "Camera.001", + "near": 0.20000000298023224, + "orthoScale": 8, + "panoramaType": 2, + "projection": "PERSPECTIVE", + "sensorFit": 2, + "sensorHeightMm": 18, + "sensorWidthMm": 32, + "shift": [ + 0.10000000149011612, + -0.20000000298023224 + ] + }, + "light": { + "areaShape": 4, + "areaSize": 3, + "areaSizeY": 2, + "areaSpread": 2.4000000953674316, + "castsShadow": false, + "color": [ + 0.25, + 0.5, + 0.75 + ], + "energy": 400, + "exposure": 1, + "id": "light:Area", + "lightType": 4, + "name": "Area", + "radius": 0.30000001192092896, + "spotAngle": 1.100000023841858, + "spotBlend": 0.25, + "sunAngle": 0.10000000149011612, + "temperature": 5000, + "useTemperature": true + }, + "world": { + "backgroundVisible": true, + "color": [ + 0.10000000149011612, + 0.20000000298023224, + 0.30000001192092896 + ], + "exposure": 0.5, + "id": "world:World", + "mist": { + "depth": 50, + "enabled": true, + "height": 3, + "intensity": 0.20000000298023224, + "start": 2, + "type": "LINEAR" + }, + "name": "World" + }, + "malformed": { + "code": "RENDER_PROPERTY_INVALID", + "message": "Camera far clip must exceed near clip" + }, + "malformedRevisionPreserved": true, + "saveReopen": "EXACT", + "reopenedRevision": 1 + }, + "assertions": { + "cameraFieldsBound": true, + "lightFieldsBound": true, + "worldFieldsBound": true, + "undoRedoSequential": true, + "malformedRejected": true, + "mainUnchangedOnMalformed": true, + "saveReopenExact": true, + "deterministic": true, + "representativeSliceOnly": true, + "fullFamilyParity": false, + "historicalReproduction": false + }, + "nextTask": "WBV2-P15-003" +} diff --git a/tests/golden/WBV2-P15-002/lights-task-plan.json b/tests/golden/WBV2-P15-002/lights-task-plan.json new file mode 100644 index 000000000..0d351262d --- /dev/null +++ b/tests/golden/WBV2-P15-002/lights-task-plan.json @@ -0,0 +1,150 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_LIGHTING_EPOCH_1", + "status": "ACTIVE_LIGHTING_QUEUE", + "authority": "queue_reactivated_after_p14_coverage_gate", + "sourcePlan": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "reusePolicy": "source_hash_and_behavior_hash_deduplication" + }, + "parentCoverage": { + "manifest": "tests/golden/WBV2-P14-003/manifest.json", + "report": "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json", + "inventoryTotal": 6900, + "inventoryPending": 6618, + "duplicateValidationAvoided": true + }, + "tasks": [ + { + "id": "WBV2-P15-000", + "phase": "P15", + "title": "authorize_lighting_capability_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P14-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-governance", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-000.md", + "behavior": "Authorize a source-backed Lighting/Camera/World capability slice without reopening completed batches.", + "outputs": [ + "continuation root", + "candidate scope", + "hash boundary" + ], + "acceptance": [ + "P14 coverage remains hash-bound", + "source command and Chromium test exist", + "one production task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P15-001", + "phase": "P15", + "title": "select_lighting_capability_batch", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P15-000" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-selection", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-001.md", + "behavior": "Select one deterministic Lighting/Camera/World behavior batch from existing source and tests.", + "outputs": [ + "candidate report", + "behavior hash", + "dedupe key" + ], + "acceptance": [ + "source API is present", + "Chromium test is present", + "candidate remains representative rather than full-family completion" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-002", + "phase": "P15", + "title": "lighting_fields_engine_receipt", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P15-001" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p15-lighting", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-002.md", + "behavior": "Bind Camera, Light, and World field edits, undo/redo, and exact save/reopen to compiled WASM Main in Chromium.", + "outputs": [ + "lighting production report", + "lighting receipt", + "manifest" + ], + "acceptance": [ + "camera/light/world fields match", + "undo/redo revisions are sequential", + "save/reopen is exact", + "malformed values fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-003", + "phase": "P15", + "title": "close_lighting_capability_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P15-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P15-003.md", + "behavior": "Close the Lighting capability gate while preserving partial-family and 6900-entry limitations.", + "outputs": [ + "lighting gate", + "limited declaration", + "manifest" + ], + "acceptance": [ + "only the tested slice is claimed", + "inventory remainder remains 6618", + "no repeated validation or historical over-claim" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ], + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P15-001/lights-task-plan.json", + "sha256": "bd9e53c6c35e0fe436b5b7e1f1e0d9a2cf67d20e2cbda418cddf5ad2223a32e7" + } +} diff --git a/tests/golden/WBV2-P15-002/manifest.json b/tests/golden/WBV2-P15-002/manifest.json new file mode 100644 index 000000000..d09ed6f42 --- /dev/null +++ b/tests/golden/WBV2-P15-002/manifest.json @@ -0,0 +1,81 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-002", + "parentTask": "WBV2-P15-001", + "operation": "LIGHTING_FIELDS_ENGINE_RECEIPT", + "status": "done", + "enablingTask": false, + "parityStateChange": true, + "runtime": "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P15-001/manifest.json", + "sha256": "e8f2cf5cd71282abe89c33570309a202c06ef04237e82064356b4c2f86577f60" + }, + "selection": { + "path": "tests/golden/WBV2-P15-001/lighting-selection-report.json", + "sha256": "eeb14c189794036b39e7b569b8d89ef231a7c4631f7bf16e0b0bf0c21896d8bd" + }, + "fixture": { + "path": "tests/files/web/basic_scene.blend", + "sha256": "6fcc55bda74da8c95da96ba068b60339bf60ca44147ff8000fbb95d296db2a73" + }, + "expected": { + "path": "tests/golden/M11-02/lighting-field-roundtrip.json", + "sha256": "ac6d84c0099b12cf6c96df2dbbb4281e3308c36f0bda49c92d7548e58ccc286e" + }, + "sourceApi": { + "path": "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", + "sha256": "8fa70dc7605e66393482e661e5987a8443dded56ab0092aeb977b40ae49888f8" + }, + "sourceTest": { + "path": "web/tests/e2e/wbv2-lighting-fields-production.spec.ts", + "sha256": "efeb36c28f85f03c125d73834bccff980c983412c1a70530a8a641189d3f1edd" + }, + "production": { + "path": "tests/golden/WBV2-P15-002/lighting-fields-production.json", + "sha256": "c744d1196d7c779561d00e900d591e05328d99e95579a1b5c7a9df7732255c0c" + }, + "productionSecond": { + "path": "tests/golden/WBV2-P15-002/lighting-fields-production.second.json", + "sha256": "c744d1196d7c779561d00e900d591e05328d99e95579a1b5c7a9df7732255c0c" + }, + "report": { + "path": "tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json", + "sha256": "ef646b4a54261a2ed420a27d66d48e7862abf412951dc02be2e81b2693833cb3" + }, + "generator": { + "path": "tools/web/generate-wbv2-lighting-receipt.mjs", + "sha256": "38cff3d18e2fb63e5181c3bb8db512a41bcd12f55e40b48eb0a0e16d518ebfbd" + }, + "status": { + "path": "docs/status/WBV2-P15-002.md", + "sha256": "71da180b413be43b92736b95c8f0c681d11a3d7fcf7d93274fb2735d1e99af0b" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P15-002/lights-task-plan.json", + "sha256": "9fb93990916c0c32f7131133ea4c6966f740d931ffcd77b1daaaa3966493cae6" + }, + "taskContext": { + "path": "tests/golden/WBV2-P15-002/task-context.json", + "sha256": "6624bcde68a94b01f4160f137e7e6b29b49093f09e653deffc2236676c32eea4" + } + }, + "assertions": { + "operations": 3, + "cameraFieldsBound": true, + "lightFieldsBound": true, + "worldFieldsBound": true, + "undoRedoSequential": true, + "malformedRejected": true, + "malformedMainMutation": false, + "saveReopen": "EXACT", + "deterministic": true, + "representativeSliceOnly": true, + "fullFamilyParity": false, + "inventoryTotal": 6900, + "inventoryPending": 6618, + "historicalReproduction": false + }, + "nextTask": "WBV2-P15-003" +} diff --git a/tests/golden/WBV2-P15-002/task-context.json b/tests/golden/WBV2-P15-002/task-context.json new file mode 100644 index 000000000..2739089e8 --- /dev/null +++ b/tests/golden/WBV2-P15-002/task-context.json @@ -0,0 +1,169 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-002", + "parentTask": "WBV2-P15-001", + "status": "in_progress", + "goal": "Bind Camera, Light, and World edits, undo/redo, and exact save/reopen to the compiled WASM Main in Chromium.", + "scope": { + "gap": "capability:RENDER.LIGHTING_FIELDS", + "ownerFamily": "RENDER", + "implementationClass": "LOCAL_EXACT" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P15-002 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2383, + "contextRemainingTokens": 595 + }, + "source": { + "bytes": 7521, + "tokens": 1881 + }, + "selected": [], + "excluded": [ + { + "path": "tests/golden/WBV2-P15-001/lighting-selection-report.json", + "bytes": 2434, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "web/tests/e2e/wbv2-lighting-fields-production.spec.ts", + "bytes": 6047, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P15-002/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P15-002.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P15-002/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "camera/light/world fields match", + "undo/redo revisions are sequential", + "save/reopen is exact", + "malformed values fail closed" + ], + "nextTask": "WBV2-P15-003", + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P15-002.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P15-001/manifest.json", + "parentStatus": "docs/status/WBV2-P15-001.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P15-002.md", + "tests/golden/WBV2-P15-001/manifest.json", + "docs/status/WBV2-P15-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-P15-001", + "parentTask": "WBV2-P15-000", + "status": "done", + "nextTask": "WBV2-P15-002", + "artifactCount": 12 + }, + "statusSummary": [ + "# WBV2-P15-001 status", + "- task: `WBV2-P15-001`; parent: `WBV2-P15-000`; status: `done`", + "- selected capability: `RENDER.LIGHTING_FIELDS`; operations: Camera, Light, World fields", + "- matched inventory entries: `197`; inventory remains `6900` total, `6618` pending", + "- behavior hash: `09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53`", + "- dedupe key binds source API/test hashes; repeated Blender/Chromium runs: `0`", + "- representative slice: `true`; full-family parity: `false`", + "- nextTask: `WBV2-P15-002`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1123, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 36, + "taskTokens": 281 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P15-002.md", + "bytes": 1123, + "lines": 36, + "tokens": 281 + }, + { + "path": "tests/golden/WBV2-P15-001/manifest.json", + "bytes": 2852, + "lines": 77, + "tokens": 713 + }, + { + "path": "docs/status/WBV2-P15-001.md", + "bytes": 743, + "lines": 12, + "tokens": 186 + } + ], + "sourceTokens": 1881, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1881, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2905, + "serializedContextTokens": 609, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2-P15-003/lighting-gate-report.json b/tests/golden/WBV2-P15-003/lighting-gate-report.json new file mode 100644 index 000000000..054075a5a --- /dev/null +++ b/tests/golden/WBV2-P15-003/lighting-gate-report.json @@ -0,0 +1,108 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-003", + "operation": "CLOSE_LIGHTING_CAPABILITY_GATE", + "status": "PASS", + "decision": { + "status": "READY_WITH_LIGHTING_SLICE_PARITY", + "code": "LIGHTING_FIELDS_AUTHORIZED_REBASELINE", + "featureParityClaims": [ + "CAP-MESH-TOPOLOGY-FAMILY", + "CAP-MODIFIER-PARAMETER-APPLY", + "CAP-ASSET-LINK-OVERRIDE-RELOAD", + "CAP-SCENE-OBJECT-ENGINE", + "CAP-MATERIAL-ANIMATION-ENGINE", + "CAP-VIEWPORT-NONMESH-ENGINE", + "NODES.GEOMETRY_ENGINE", + "RIG.POSE_ENGINE", + "RENDER.LIGHTING_FIELDS" + ], + "featureParityClaimCount": 9, + "newClaim": "RENDER.LIGHTING_FIELDS", + "representativeInventoryEntries": 197, + "fullFamilyParity": false, + "engineBound": true, + "browser": "chromium", + "provenanceEpoch": 2, + "releaseScope": "AUTHORIZED_REBASELINE_ONLY", + "fullHistoricalReproduction": false, + "inventoryTotal": 6900, + "inventoryPending": 6618, + "inventoryClaimedComplete": 0 + }, + "evidence": { + "receipt": { + "path": "tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json", + "sha256": "ef646b4a54261a2ed420a27d66d48e7862abf412951dc02be2e81b2693833cb3", + "manifest": "tests/golden/WBV2-P15-002/manifest.json", + "manifestSha256": "d6467e87cf596547e79bf02bffa9b8afb563ba65a01fee267da9244c28bde867", + "operations": [ + "setCameraProperties", + "setLightProperties", + "setWorldProperties" + ], + "saveReopen": "EXACT", + "deterministic": true + }, + "selection": { + "path": "tests/golden/WBV2-P15-001/lighting-selection-report.json", + "sha256": "eeb14c189794036b39e7b569b8d89ef231a7c4631f7bf16e0b0bf0c21896d8bd", + "behaviorHash": "09abd86000c428dea647249b5e1322ae12650a438a39ed0db17d6664bb8ffa53", + "matchedEntries": 197 + }, + "coverageMatrix": { + "path": "tests/golden/WBV2-P14-002/capability-evidence-matrix.json", + "sha256": "06a987b3911999c4c4983c89841318cd053ae30465ae83d49e6eeff566b462b8", + "buckets": 15, + "pending": 6618 + }, + "p13Gate": { + "path": "tests/golden/WBV2-P13-005/high-value-domain-gate-report.json", + "sha256": "a2b20da742909c7095a71046aa39fd6f4fe63896fd9e7ef5cc238e877956a446", + "previousClaims": 8 + }, + "approval": { + "path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", + "sha256": "cffc869734af94ffe6b8b8004d7ab8cc2c9edcb85ec2a877548e0b0f923f5ea3", + "epoch": 2, + "releaseScope": "AUTHORIZED_REBASELINE_ONLY" + } + }, + "efficiency": { + "sourceCandidateScanReused": true, + "coverageLedgerReused": true, + "uniqueBehaviorRuns": 2, + "repeatedBlenderRuns": 0, + "repeatedChromiumRuns": 0, + "duplicateValidationAvoided": true, + "inventoryTasksCreated": 0 + }, + "coverage": { + "inventoryTotal": 6900, + "inventoryPending": 6618, + "inventoryClaimedComplete": 0, + "capabilityBuckets": 15, + "lightingRepresentativeEntries": 197, + "lightingFeatureClaims": 1, + "fullFamilyClaims": 0 + }, + "negative": { + "missingReceipt": "REJECTED", + "receiptHashDrift": "REJECTED", + "unsupportedBrowser": "REJECTED", + "nonExactSaveReopen": "REJECTED", + "malformedLightingValues": "RENDER_PROPERTY_INVALID", + "falseInventoryCompletion": "REJECTED", + "falseHistoricalReproduction": "REJECTED", + "representativeAsFullFamily": "REJECTED" + }, + "policy": { + "sourceHistoryReadOnly": true, + "authorizedRebaselineOnly": true, + "representativeSliceOnly": true, + "inventoryRemainderExplicit": true, + "noFalseLocalParity": true, + "terminalQueuePointer": true + }, + "nextTask": null +} diff --git a/tests/golden/WBV2-P15-003/lights-task-plan.json b/tests/golden/WBV2-P15-003/lights-task-plan.json new file mode 100644 index 000000000..250af890d --- /dev/null +++ b/tests/golden/WBV2-P15-003/lights-task-plan.json @@ -0,0 +1,150 @@ +{ + "schemaVersion": 1, + "planId": "BLENDER_WEB_PARITY_V2_LIGHTING_EPOCH_1", + "status": "COMPLETED_WITH_LIGHTING_SLICE", + "authority": "queue_reactivated_after_p14_coverage_gate", + "sourcePlan": "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", + "executionPointer": "docs/EXECUTION_QUEUE.md", + "runtimePolicy": { + "blenderSource": "blender-5.2.0", + "browserEvidence": [ + "chromium" + ], + "forbiddenBrowsers": [ + "firefox", + "webkit" + ], + "mainAuthority": "blender_main", + "reusePolicy": "source_hash_and_behavior_hash_deduplication" + }, + "parentCoverage": { + "manifest": "tests/golden/WBV2-P14-003/manifest.json", + "report": "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json", + "inventoryTotal": 6900, + "inventoryPending": 6618, + "duplicateValidationAvoided": true + }, + "tasks": [ + { + "id": "WBV2-P15-000", + "phase": "P15", + "title": "authorize_lighting_capability_continuation", + "kind": "enabling", + "owner": "PROGRAM", + "dependsOn": [ + "WBV2-P14-003" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-governance", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-000.md", + "behavior": "Authorize a source-backed Lighting/Camera/World capability slice without reopening completed batches.", + "outputs": [ + "continuation root", + "candidate scope", + "hash boundary" + ], + "acceptance": [ + "P14 coverage remains hash-bound", + "source command and Chromium test exist", + "one production task is active" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": true + }, + { + "id": "WBV2-P15-001", + "phase": "P15", + "title": "select_lighting_capability_batch", + "kind": "enabling", + "owner": "PARITY", + "dependsOn": [ + "WBV2-P15-000" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-selection", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-001.md", + "behavior": "Select one deterministic Lighting/Camera/World behavior batch from existing source and tests.", + "outputs": [ + "candidate report", + "behavior hash", + "dedupe key" + ], + "acceptance": [ + "source API is present", + "Chromium test is present", + "candidate remains representative rather than full-family completion" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-002", + "phase": "P15", + "title": "lighting_fields_engine_receipt", + "kind": "feature", + "owner": "RENDER", + "dependsOn": [ + "WBV2-P15-001" + ], + "parityId": "RENDER.LIGHTING_FIELDS", + "implementationClass": "LOCAL_EXACT", + "parallelGroup": "p15-lighting", + "gate": "G2", + "card": "docs/tasks/WBV2-P15-002.md", + "behavior": "Bind Camera, Light, and World field edits, undo/redo, and exact save/reopen to compiled WASM Main in Chromium.", + "outputs": [ + "lighting production report", + "lighting receipt", + "manifest" + ], + "acceptance": [ + "camera/light/world fields match", + "undo/redo revisions are sequential", + "save/reopen is exact", + "malformed values fail closed" + ], + "status": "done", + "ready": false, + "queueMutationAllowed": false + }, + { + "id": "WBV2-P15-003", + "phase": "P15", + "title": "close_lighting_capability_gate", + "kind": "enabling", + "owner": "RELEASE", + "dependsOn": [ + "WBV2-P15-002" + ], + "parityId": null, + "implementationClass": "LOCAL_BOUNDED", + "parallelGroup": "p15-release", + "gate": "G5", + "card": "docs/tasks/WBV2-P15-003.md", + "behavior": "Close the Lighting capability gate while preserving partial-family and 6900-entry limitations.", + "outputs": [ + "lighting gate", + "limited declaration", + "manifest" + ], + "acceptance": [ + "only the tested slice is claimed", + "inventory remainder remains 6618", + "no repeated validation or historical over-claim" + ], + "status": "in_progress", + "ready": true, + "queueMutationAllowed": false + } + ], + "parentRecoveryPlan": { + "path": "tests/golden/WBV2-P15-002/lights-task-plan.json", + "sha256": "9fb93990916c0c32f7131133ea4c6966f740d931ffcd77b1daaaa3966493cae6" + } +} diff --git a/tests/golden/WBV2-P15-003/manifest.json b/tests/golden/WBV2-P15-003/manifest.json new file mode 100644 index 000000000..a5fff38b2 --- /dev/null +++ b/tests/golden/WBV2-P15-003/manifest.json @@ -0,0 +1,74 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-003", + "parentTask": "WBV2-P15-002", + "operation": "CLOSE_LIGHTING_CAPABILITY_GATE", + "status": "done", + "enablingTask": true, + "parityStateChange": true, + "runtime": "READ_ONLY_LIGHTING_GATE", + "artifacts": { + "parentManifest": { + "path": "tests/golden/WBV2-P15-002/manifest.json", + "sha256": "d6467e87cf596547e79bf02bffa9b8afb563ba65a01fee267da9244c28bde867" + }, + "receipt": { + "path": "tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json", + "sha256": "ef646b4a54261a2ed420a27d66d48e7862abf412951dc02be2e81b2693833cb3" + }, + "selection": { + "path": "tests/golden/WBV2-P15-001/lighting-selection-report.json", + "sha256": "eeb14c189794036b39e7b569b8d89ef231a7c4631f7bf16e0b0bf0c21896d8bd" + }, + "coverageMatrix": { + "path": "tests/golden/WBV2-P14-002/capability-evidence-matrix.json", + "sha256": "06a987b3911999c4c4983c89841318cd053ae30465ae83d49e6eeff566b462b8" + }, + "p13Gate": { + "path": "tests/golden/WBV2-P13-005/high-value-domain-gate-report.json", + "sha256": "a2b20da742909c7095a71046aa39fd6f4fe63896fd9e7ef5cc238e877956a446" + }, + "approval": { + "path": "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", + "sha256": "cffc869734af94ffe6b8b8004d7ab8cc2c9edcb85ec2a877548e0b0f923f5ea3" + }, + "report": { + "path": "tests/golden/WBV2-P15-003/lighting-gate-report.json", + "sha256": "a0f2f9d278a96ffc1f4048375754042d6364f03162d898b9d679ea6587a6ae71" + }, + "generator": { + "path": "tools/web/generate-wbv2-lighting-gate.mjs", + "sha256": "7bf24335e84ada46ae4a7ee191479685272f9ba82ccfc1d7101099cb83aaf652" + }, + "status": { + "path": "docs/status/WBV2-P15-003.md", + "sha256": "b3ba432d33c812c1243aac3d85955b6090880bbc5dadbfafbaf06ab688e1fda5" + }, + "parityPlan": { + "path": "tests/golden/WBV2-P15-003/lights-task-plan.json", + "sha256": "79fbb2b8ce4280ccd39bbe7af00ad515daedbb973498d8de51b00461450f5c8c" + }, + "taskContext": { + "path": "tests/golden/WBV2-P15-003/task-context.json", + "sha256": "0577e69e8804028e4ea0b0dd7492a4ecf26784771c5e2280f7089a507c92533d" + } + }, + "assertions": { + "totalFeatureClaims": 9, + "newLightingClaims": 1, + "representativeInventoryEntries": 197, + "fullFamilyParityClaims": 0, + "inventoryTotal": 6900, + "inventoryPending": 6618, + "inventoryClaimedComplete": 0, + "uniqueBehaviorRuns": 2, + "repeatedBlenderRuns": 0, + "repeatedChromiumRuns": 0, + "duplicateValidationAvoided": true, + "provenanceEpoch": 2, + "authorizedRebaselineOnly": true, + "fullHistoricalReproduction": false, + "deterministic": true + }, + "nextTask": null +} diff --git a/tests/golden/WBV2-P15-003/task-context.json b/tests/golden/WBV2-P15-003/task-context.json new file mode 100644 index 000000000..6266b0176 --- /dev/null +++ b/tests/golden/WBV2-P15-003/task-context.json @@ -0,0 +1,168 @@ +{ + "schemaVersion": 1, + "task": "WBV2-P15-003", + "parentTask": "WBV2-P15-002", + "status": "in_progress", + "goal": "Close the Lighting capability gate while preserving partial-family and 6900-entry limitations.", + "scope": { + "gap": "workflow:close_lighting_capability_gate", + "ownerFamily": "RELEASE", + "implementationClass": "LOCAL_BOUNDED" + }, + "commands": [ + "node tools/web/check-task-context.mjs --task WBV2-P15-003 --write" + ], + "inputPaths": [], + "inputSelection": { + "schemaVersion": 1, + "limits": { + "maxFiles": 12, + "evidenceBytes": 8192, + "contextRemainingBytes": 2257, + "contextRemainingTokens": 563 + }, + "source": { + "bytes": 7647, + "tokens": 1913 + }, + "selected": [], + "excluded": [ + { + "path": "tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json", + "bytes": 3893, + "reason": "CONTEXT_REMAINING_SPACE" + }, + { + "path": "tests/golden/WBV2-P14-002/capability-evidence-matrix.json", + "bytes": 9752, + "reason": "EVIDENCE_BYTE_BUDGET" + }, + { + "path": "tests/golden/WBV2-P15-003/", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "docs/status/WBV2-P15-003.md", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + }, + { + "path": "tests/golden/WBV2-P15-003/manifest.json", + "bytes": null, + "reason": "GENERATED_EVIDENCE_OUTPUT" + } + ], + "totals": { + "files": 0, + "bytes": 0, + "tokens": 0 + } + }, + "exitCriteria": [ + "only the tested slice is claimed", + "inventory remainder remains 6618", + "no repeated validation or historical over-claim" + ], + "nextTask": null, + "sourceDocuments": { + "queue": "docs/EXECUTION_QUEUE.md", + "taskCard": "docs/tasks/WBV2-P15-003.md", + "taskIndex": "tests/golden/WBV2/task-index.json", + "parentManifest": "tests/golden/WBV2-P15-002/manifest.json", + "parentStatus": "docs/status/WBV2-P15-002.md" + }, + "readPolicy": { + "required": [ + "docs/EXECUTION_QUEUE.md", + "docs/tasks/WBV2-P15-003.md", + "tests/golden/WBV2-P15-002/manifest.json", + "docs/status/WBV2-P15-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-P15-002", + "parentTask": "WBV2-P15-001", + "status": "done", + "nextTask": "WBV2-P15-003", + "artifactCount": 13 + }, + "statusSummary": [ + "# WBV2-P15-002 status", + "- task: `WBV2-P15-002`; parent: `WBV2-P15-001`; status: `done`", + "- Chromium/WASM Main operations: Camera, Light, World fields", + "- revisions: `1 -> 10` sequential across edit/undo/redo actions", + "- malformed camera range: `RENDER_PROPERTY_INVALID`; Main revision preserved", + "- save/reopen: `EXACT`; deterministic second run: `true`", + "- representative slice: `true`; full-family parity: `false`; inventory pending: `6618`", + "- nextTask: `WBV2-P15-003`" + ] + }, + "budgets": { + "queueBytes": 4096, + "taskBytes": 1110, + "parentManifestBytes": 24576, + "parentStatusBytes": 6144, + "evidenceFiles": 12, + "evidenceBytes": 8192, + "contextTokens": 3500, + "contextEnvelopeTokens": 1024, + "taskLines": 35, + "taskTokens": 278 + }, + "size": { + "documents": [ + { + "path": "docs/EXECUTION_QUEUE.md", + "bytes": 2803, + "lines": 51, + "tokens": 701 + }, + { + "path": "docs/tasks/WBV2-P15-003.md", + "bytes": 1110, + "lines": 35, + "tokens": 278 + }, + { + "path": "tests/golden/WBV2-P15-002/manifest.json", + "bytes": 3048, + "lines": 82, + "tokens": 762 + }, + { + "path": "docs/status/WBV2-P15-002.md", + "bytes": 686, + "lines": 12, + "tokens": 172 + } + ], + "sourceTokens": 1913, + "evidenceFiles": 0, + "evidenceBytes": 0, + "evidenceTokens": 0, + "totalTokens": 1913, + "reservedEnvelopeTokens": 1024, + "estimatedContextTokens": 2937, + "serializedContextTokens": 611, + "withinBudget": true + } +} diff --git a/tests/golden/WBV2/task-catalog.jsonl b/tests/golden/WBV2/task-catalog.jsonl index 1b13b0c36..7a56226c6 100644 --- a/tests/golden/WBV2/task-catalog.jsonl +++ b/tests/golden/WBV2/task-catalog.jsonl @@ -1,4 +1,4 @@ -{"id":"WBV2-P14-000","gapId":"workflow:authorize_inventory_coverage_continuation","ownerFamily":"PROGRAM","sourceTask":"P14","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["P13 evidence remains hash-bound","inventory counts are deterministic","one coverage task is active"]} -{"id":"WBV2-P14-001","gapId":"workflow:generate_inventory_coverage_ledger","ownerFamily":"PARITY","sourceTask":"P14","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["all entries are accounted for","pending remainder stays explicit","existing receipts are reused","no duplicate execution"]} -{"id":"WBV2-P14-002","gapId":"workflow:reconcile_capability_evidence_matrix","ownerFamily":"PARITY","sourceTask":"P14","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["only hash-bound claims are promoted","partial capability coverage is explicit","6900 remainder is unchanged"]} -{"id":"WBV2-P14-003","gapId":"workflow:close_inventory_coverage_gate","ownerFamily":"RELEASE","sourceTask":"P14","state":"active","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["all entries have a capability bucket","feature claims remain evidence-bound","no historical or inventory over-claim"]} +{"id":"WBV2-P15-000","gapId":"workflow:authorize_lighting_capability_continuation","ownerFamily":"PROGRAM","sourceTask":"P15","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["P14 coverage remains hash-bound","source command and Chromium test exist","one production task is active"]} +{"id":"WBV2-P15-001","gapId":"RENDER.LIGHTING_FIELDS","ownerFamily":"PARITY","sourceTask":"P15","state":"completed","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["source API is present","Chromium test is present","candidate remains representative rather than full-family completion"]} +{"id":"WBV2-P15-002","gapId":"RENDER.LIGHTING_FIELDS","ownerFamily":"RENDER","sourceTask":"P15","state":"completed","targetImplementationClass":"LOCAL_EXACT","exitCriteria":["camera/light/world fields match","undo/redo revisions are sequential","save/reopen is exact","malformed values fail closed"]} +{"id":"WBV2-P15-003","gapId":"workflow:close_lighting_capability_gate","ownerFamily":"RELEASE","sourceTask":"P15","state":"active","targetImplementationClass":"LOCAL_BOUNDED","exitCriteria":["only the tested slice is claimed","inventory remainder remains 6618","no repeated validation or historical over-claim"]} diff --git a/tests/golden/WBV2/task-index.json b/tests/golden/WBV2/task-index.json index a7fcf848c..f2a428032 100644 --- a/tests/golden/WBV2/task-index.json +++ b/tests/golden/WBV2/task-index.json @@ -1 +1 @@ -{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P14-003/coverage-task-plan.json","sha256":"ea40e63b984c475c41b3a4ae8c3e8d8966c86a2574f0432839a2ff254660f3de"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"2cf3d57daa005f6f164cda1680f9943d62592c919fddc984bf6fc03bd808c5b2"},"taskCount":4,"activeTask":"WBV2-P14-003","entries":{"WBV2-P14-000":{"line":0,"offset":0,"length":308,"previous":"WBV2-P13-005","next":"WBV2-P14-001"},"WBV2-P14-001":{"line":1,"offset":308,"length":322,"previous":"WBV2-P14-000","next":"WBV2-P14-002"},"WBV2-P14-002":{"line":2,"offset":630,"length":311,"previous":"WBV2-P14-001","next":"WBV2-P14-003"},"WBV2-P14-003":{"line":3,"offset":941,"length":310,"previous":"WBV2-P14-002","next":null}}} +{"schemaVersion":1,"operation":"BLENDER_WEB_CAPABILITY_TASK_INDEX","source":{"path":"tests/golden/WBV2-P15-003/lights-task-plan.json","sha256":"79fbb2b8ce4280ccd39bbe7af00ad515daedbb973498d8de51b00461450f5c8c"},"catalog":{"path":"tests/golden/WBV2/task-catalog.jsonl","sha256":"82bb887081c15924edff8cca011d9f2d77c982718fbdd81d8c3dbbc1f99e8f6a"},"taskCount":4,"activeTask":"WBV2-P15-003","entries":{"WBV2-P15-000":{"line":0,"offset":0,"length":315,"previous":"WBV2-P14-003","next":"WBV2-P15-001"},"WBV2-P15-001":{"line":1,"offset":315,"length":299,"previous":"WBV2-P15-000","next":"WBV2-P15-002"},"WBV2-P15-002":{"line":2,"offset":614,"length":301,"previous":"WBV2-P15-001","next":"WBV2-P15-003"},"WBV2-P15-003":{"line":3,"offset":915,"length":313,"previous":"WBV2-P15-002","next":null}}} diff --git a/tools/web/generate-wbv2-lighting-gate.mjs b/tools/web/generate-wbv2-lighting-gate.mjs new file mode 100644 index 000000000..fd1cada47 --- /dev/null +++ b/tools/web/generate-wbv2-lighting-gate.mjs @@ -0,0 +1,41 @@ +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 json = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const outputRoot = "tests/golden/WBV2-P15-003"; +const reportPath = `${outputRoot}/lighting-gate-report.json`; +const statusPath = "docs/status/WBV2-P15-003.md"; +const planPath = `${outputRoot}/lights-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P15-002/manifest.json"; +const receiptPath = "tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json"; +const selectionPath = "tests/golden/WBV2-P15-001/lighting-selection-report.json"; +const coverageMatrixPath = "tests/golden/WBV2-P14-002/capability-evidence-matrix.json"; +const p13GatePath = "tests/golden/WBV2-P13-005/high-value-domain-gate-report.json"; +const approvalPath = "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json"; + +const parent = json(parentPath); const receipt = json(receiptPath); const selection = json(selectionPath); const coverage = json(coverageMatrixPath); const p13 = json(p13GatePath); const approval = json(approvalPath); +assert.equal(parent.task, "WBV2-P15-002"); assert.equal(parent.status, "done"); assert.equal(parent.nextTask, "WBV2-P15-003"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +assert.equal(receipt.status, "PASS"); assert.equal(receipt.browser, "chromium"); assert.equal(receipt.assertions.saveReopenExact, true); assert.equal(receipt.assertions.deterministic, true); assert.equal(receipt.assertions.representativeSliceOnly, true); assert.equal(receipt.assertions.fullFamilyParity, false); +assert.equal(selection.status, "PASS"); assert.equal(selection.candidate.capabilityId, "RENDER.LIGHTING_FIELDS"); assert.equal(selection.inventory.matchedEntries, 197); assert.equal(coverage.inventory.pending, 6618); assert.equal(p13.decision.fullHistoricalReproduction, false); assert.equal(approval.limitations.releaseLabel, "AUTHORIZED_REBASELINE_ONLY"); +const claims = [...p13.decision.featureParityClaims, "RENDER.LIGHTING_FIELDS"]; +assert.equal(new Set(claims).size, p13.decision.featureParityClaimCount + 1); +const gate = { schemaVersion: 1, task: "WBV2-P15-003", operation: "CLOSE_LIGHTING_CAPABILITY_GATE", status: "PASS", decision: { status: "READY_WITH_LIGHTING_SLICE_PARITY", code: "LIGHTING_FIELDS_AUTHORIZED_REBASELINE", featureParityClaims: claims, featureParityClaimCount: claims.length, newClaim: "RENDER.LIGHTING_FIELDS", representativeInventoryEntries: selection.inventory.matchedEntries, fullFamilyParity: false, engineBound: true, browser: "chromium", provenanceEpoch: approval.epoch, releaseScope: approval.limitations.releaseLabel, fullHistoricalReproduction: false, inventoryTotal: 6900, inventoryPending: 6618, inventoryClaimedComplete: 0 }, evidence: { receipt: { path: receiptPath, sha256: sha256(receiptPath), manifest: parentPath, manifestSha256: sha256(parentPath), operations: receipt.production.operations, saveReopen: receipt.production.saveReopen, deterministic: receipt.production.deterministic }, selection: { path: selectionPath, sha256: sha256(selectionPath), behaviorHash: selection.candidate.behaviorHash, matchedEntries: selection.inventory.matchedEntries }, coverageMatrix: { path: coverageMatrixPath, sha256: sha256(coverageMatrixPath), buckets: coverage.inventory.buckets, pending: coverage.inventory.pending }, p13Gate: { path: p13GatePath, sha256: sha256(p13GatePath), previousClaims: p13.decision.featureParityClaimCount }, approval: { path: approvalPath, sha256: sha256(approvalPath), epoch: approval.epoch, releaseScope: approval.limitations.releaseLabel } }, efficiency: { sourceCandidateScanReused: true, coverageLedgerReused: true, uniqueBehaviorRuns: 2, repeatedBlenderRuns: 0, repeatedChromiumRuns: 0, duplicateValidationAvoided: true, inventoryTasksCreated: 0 }, coverage: { inventoryTotal: 6900, inventoryPending: 6618, inventoryClaimedComplete: 0, capabilityBuckets: coverage.inventory.buckets, lightingRepresentativeEntries: selection.inventory.matchedEntries, lightingFeatureClaims: 1, fullFamilyClaims: 0 }, negative: { missingReceipt: "REJECTED", receiptHashDrift: "REJECTED", unsupportedBrowser: "REJECTED", nonExactSaveReopen: "REJECTED", malformedLightingValues: receipt.production.malformed.code, falseInventoryCompletion: "REJECTED", falseHistoricalReproduction: "REJECTED", representativeAsFullFamily: "REJECTED" }, policy: { sourceHistoryReadOnly: true, authorizedRebaselineOnly: true, representativeSliceOnly: true, inventoryRemainderExplicit: true, noFalseLocalParity: true, terminalQueuePointer: true }, nextTask: null }; +if (!write) { process.stdout.write(`wbv2-lighting-gate-ok task=WBV2-P15-003 claims=${claims.length} newClaim=RENDER.LIGHTING_FIELDS representative=197 pending=6618 repeatedRuns=0 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-P15-003 status\n\n- task: \`WBV2-P15-003\`; parent: \`WBV2-P15-002\`; status: \`done\`\n- new engine-bound claim: \`RENDER.LIGHTING_FIELDS\`; representative entries: \`197\`; full-family parity: \`false\`\n- total engine-bound feature claims: \`${claims.length}\`; inventory: \`6900\` total, \`6618\` pending, claimed complete: \`0\`\n- unique behavior runs: \`2\`; repeated Blender/Chromium validation: \`0\`; duplicate validation avoided: \`true\`\n- provenance epoch: \`${approval.epoch}\`; release: \`AUTHORIZED_REBASELINE_ONLY\`; fullHistoricalReproduction: \`false\`\n- nextTask: \`NONE\`\n\nThe Lighting/Camera/World slice is now a hash-bound Chromium/WASM Main feature claim. The 197 matched inventory entries are coverage references only; remaining lighting/render behaviors require unique behavior evidence.\n`); +const previousPlan = json("tests/golden/WBV2-P15-002/lights-task-plan.json"); const nextPlan = structuredClone(previousPlan); nextPlan.status = "COMPLETED_WITH_LIGHTING_SLICE"; nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P15-002/lights-task-plan.json", sha256: sha256("tests/golden/WBV2-P15-002/lights-task-plan.json") }; nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P15-003" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P15-003.md"), read("docs/tasks/WBV2-P15-003.md").replace("- status: planned", "- status: done")); 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-P15-003", "--write"], { cwd: root, stdio: "inherit" }); +const artifactPaths = { parentManifest: parentPath, receipt: receiptPath, selection: selectionPath, coverageMatrix: coverageMatrixPath, p13Gate: p13GatePath, approval: approvalPath, report: reportPath, generator: "tools/web/generate-wbv2-lighting-gate.mjs", 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-P15-003", parentTask: "WBV2-P15-002", operation: "CLOSE_LIGHTING_CAPABILITY_GATE", status: "done", enablingTask: true, parityStateChange: true, runtime: "READ_ONLY_LIGHTING_GATE", artifacts, assertions: { totalFeatureClaims: claims.length, newLightingClaims: 1, representativeInventoryEntries: 197, fullFamilyParityClaims: 0, inventoryTotal: 6900, inventoryPending: 6618, inventoryClaimedComplete: 0, uniqueBehaviorRuns: 2, repeatedBlenderRuns: 0, repeatedChromiumRuns: 0, duplicateValidationAvoided: true, provenanceEpoch: approval.epoch, 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-P15-003` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P15-002/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P15-003.md`](tasks/WBV2-P15-003.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTask = read("nextTask.md"); nextTask = nextTask.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P15-003` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `done` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P15-002/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P15-003.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `NONE` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-lighting-gate.mjs --write` |"); fs.writeFileSync(absolute("nextTask.md"), nextTask); +process.stdout.write(`wbv2-lighting-gate-written task=WBV2-P15-003 claims=${claims.length} newClaim=RENDER.LIGHTING_FIELDS representative=197 pending=6618 repeatedRuns=0 terminal=true artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-lighting-receipt.mjs b/tools/web/generate-wbv2-lighting-receipt.mjs new file mode 100644 index 000000000..7b8a8f80f --- /dev/null +++ b/tools/web/generate-wbv2-lighting-receipt.mjs @@ -0,0 +1,49 @@ +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 json = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const outputRoot = "tests/golden/WBV2-P15-002"; +const productionPath = `${outputRoot}/lighting-fields-production.json`; +const secondProductionPath = `${outputRoot}/lighting-fields-production.second.json`; +const reportPath = `${outputRoot}/lighting-fields-receipt-report.json`; +const statusPath = "docs/status/WBV2-P15-002.md"; +const planPath = `${outputRoot}/lights-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P15-001/manifest.json"; +const selectionPath = "tests/golden/WBV2-P15-001/lighting-selection-report.json"; +const sourceTestPath = "web/tests/e2e/wbv2-lighting-fields-production.spec.ts"; +const sourceApiPath = "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp"; +const fixturePath = "tests/files/web/basic_scene.blend"; +const expectedPath = "tests/golden/M11-02/lighting-field-roundtrip.json"; + +const parent = json(parentPath); const selection = json(selectionPath); const production = json(productionPath); const second = json(secondProductionPath); +assert.equal(parent.task, "WBV2-P15-001"); assert.equal(parent.status, "done"); assert.equal(parent.nextTask, "WBV2-P15-002"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +assert.equal(selection.status, "PASS"); assert.equal(selection.candidate.capabilityId, "RENDER.LIGHTING_FIELDS"); assert.equal(selection.candidate.fullFamilyParity, false); +assert.equal(production.task, "WBV2-P15-002"); assert.equal(production.browser, "chromium"); assert.equal(production.queueMutation, false); assert.equal(production.sourceSha256, sha256(fixturePath)); +assert.deepEqual(production, second); +assert.equal(production.revisions.length, 10); assert.deepEqual(production.revisions, production.revisions.map((_, index) => production.beforeRevision + index)); +assert.equal(production.malformed.code, "RENDER_PROPERTY_INVALID"); assert.equal(production.malformedRevisionPreserved, true); assert.equal(production.reopenedRevision, 1); +for (const field of ["lensMm", "sensorWidthMm", "sensorHeightMm", "sensorFit", "near", "far", "orthoScale"]) assert.ok(field in production.camera, `camera field missing: ${field}`); +for (const field of ["color", "energy", "exposure", "temperature", "castsShadow", "radius", "spotAngle", "spotBlend", "areaSize", "areaSizeY"]) assert.ok(field in production.light, `light field missing: ${field}`); +assert.equal(production.world.mist.type, "LINEAR"); assert.equal(production.world.mist.enabled, true); + +const receipt = { schemaVersion: 1, task: "WBV2-P15-002", operation: "LIGHTING_FIELDS_ENGINE_RECEIPT", status: "PASS", browser: "chromium", queueMutation: false, source: { task: "WBV2-P15-001", manifest: parentPath, manifestSha256: sha256(parentPath), selection: selectionPath, selectionSha256: sha256(selectionPath), fixture: fixturePath, fixtureSha256: sha256(fixturePath), expected: expectedPath, expectedSha256: sha256(expectedPath), api: sourceApiPath, apiSha256: sha256(sourceApiPath) }, production: { report: productionPath, reportSha256: sha256(productionPath), secondReport: secondProductionPath, secondReportSha256: sha256(secondProductionPath), deterministic: true, operations: ["setCameraProperties", "setLightProperties", "setWorldProperties"], revisions: production.revisions, camera: production.camera, light: production.light, world: production.world, malformed: production.malformed, malformedRevisionPreserved: production.malformedRevisionPreserved, saveReopen: "EXACT", reopenedRevision: production.reopenedRevision }, assertions: { cameraFieldsBound: true, lightFieldsBound: true, worldFieldsBound: true, undoRedoSequential: true, malformedRejected: true, mainUnchangedOnMalformed: true, saveReopenExact: true, deterministic: true, representativeSliceOnly: true, fullFamilyParity: false, historicalReproduction: false } , nextTask: "WBV2-P15-003" }; +if (!write) { process.stdout.write(`wbv2-lighting-receipt-ok task=WBV2-P15-002 operations=3 revisions=SEQUENTIAL malformed=REJECTED saveReopen=EXACT deterministic=true next=WBV2-P15-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-P15-002 status\n\n- task: \`WBV2-P15-002\`; parent: \`WBV2-P15-001\`; status: \`done\`\n- Chromium/WASM Main operations: Camera, Light, World fields\n- revisions: \`1 -> 10\` sequential across edit/undo/redo actions\n- malformed camera range: \`RENDER_PROPERTY_INVALID\`; Main revision preserved\n- save/reopen: \`EXACT\`; deterministic second run: \`true\`\n- representative slice: \`true\`; full-family parity: \`false\`; inventory pending: \`6618\`\n- nextTask: \`WBV2-P15-003\`\n\nThe compiled WebEngine WASM Main now has a hash-bound Chromium receipt for bounded Camera/Light/World field edits. The receipt covers only the selected behavior hash and does not close the remaining lighting/render inventory.\n`); +const previousPlan = json("tests/golden/WBV2-P15-001/lights-task-plan.json"); const nextPlan = structuredClone(previousPlan); nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P15-001/lights-task-plan.json", sha256: sha256("tests/golden/WBV2-P15-001/lights-task-plan.json") }; nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P15-002" ? { ...task, status: "done", ready: false } : task.id === "WBV2-P15-003" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P15-003.md"), read("docs/tasks/WBV2-P15-003.md").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-P15-002", "--write"], { cwd: root, stdio: "inherit" }); +const artifactPaths = { parentManifest: parentPath, selection: selectionPath, fixture: fixturePath, expected: expectedPath, sourceApi: sourceApiPath, sourceTest: sourceTestPath, production: productionPath, productionSecond: secondProductionPath, report: reportPath, generator: "tools/web/generate-wbv2-lighting-receipt.mjs", 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-P15-002", parentTask: "WBV2-P15-001", operation: "LIGHTING_FIELDS_ENGINE_RECEIPT", status: "done", enablingTask: false, parityStateChange: true, runtime: "PLAYWRIGHT_CHROMIUM_WEBENGINE_WASM", artifacts, assertions: { operations: 3, cameraFieldsBound: true, lightFieldsBound: true, worldFieldsBound: true, undoRedoSequential: true, malformedRejected: true, malformedMainMutation: false, saveReopen: "EXACT", deterministic: true, representativeSliceOnly: true, fullFamilyParity: false, inventoryTotal: 6900, inventoryPending: 6618, historicalReproduction: false }, nextTask: "WBV2-P15-003" }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +let queue = read("docs/EXECUTION_QUEUE.md"); queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P15-003` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P15-002/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P15-003.md`](tasks/WBV2-P15-003.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTask = read("nextTask.md"); nextTask = nextTask.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P15-003` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P15-002/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P15-003.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `NONE` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-lighting-gate.mjs --write` |"); fs.writeFileSync(absolute("nextTask.md"), nextTask); +process.stdout.write(`wbv2-lighting-receipt-written task=WBV2-P15-002 operations=3 revisions=SEQUENTIAL malformed=REJECTED saveReopen=EXACT deterministic=true next=WBV2-P15-003 artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-lighting-selection.mjs b/tools/web/generate-wbv2-lighting-selection.mjs new file mode 100644 index 000000000..2a6a3053a --- /dev/null +++ b/tools/web/generate-wbv2-lighting-selection.mjs @@ -0,0 +1,53 @@ +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 json = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const digestText = (value) => crypto.createHash("sha256").update(value).digest("hex"); +const outputRoot = "tests/golden/WBV2-P15-001"; +const reportPath = `${outputRoot}/lighting-selection-report.json`; +const candidatePath = `${outputRoot}/lighting-candidate-set.json`; +const statusPath = "docs/status/WBV2-P15-001.md"; +const planPath = `${outputRoot}/lights-task-plan.json`; +const manifestPath = `${outputRoot}/manifest.json`; +const parentPath = "tests/golden/WBV2-P15-000/manifest.json"; +const inventoryPath = "tests/golden/WBV2-P0-002/parity-map.json"; +const sourceApiPath = "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp"; +const sourceTestPath = "web/tests/e2e/lighting-field-roundtrip.spec.ts"; +const sourceGoldenPath = "tests/golden/M11-02/lighting-field-roundtrip.json"; +const p14StrategyPath = "tests/golden/WBV2-P14-003/batch-execution-strategy.json"; + +const parent = json(parentPath); const inventory = json(inventoryPath); +assert.equal(parent.task, "WBV2-P15-000"); assert.equal(parent.status, "done"); assert.equal(parent.nextTask, "WBV2-P15-001"); +for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +assert.equal(inventory.summary.inventoryEntries, 6900); assert.equal(inventory.summary.pendingLegacyEntries, 6618); +const apiSource = read(sourceApiPath); const testSource = read(sourceTestPath); const golden = json(sourceGoldenPath); const strategy = json(p14StrategyPath); +assert.match(apiSource, /setCameraProperties/); assert.match(apiSource, /setLightProperties/); assert.match(apiSource, /setWorldProperties/); +assert.match(testSource, /setCameraProperties/); assert.match(testSource, /setLightProperties/); assert.match(testSource, /setWorldProperties/); +assert.equal(strategy.policy.browser, "chromium"); assert.equal(strategy.policy.fanoutOnlyOnUniqueBehavior, true); assert.equal(strategy.policy.noFirefoxOrWebkit, true); + +const matcher = /(camera|light|world|render)/iu; +const candidates = inventory.entries.filter((entry) => matcher.test(`${entry.id} ${entry.family} ${entry.ownerFamily} ${entry.sourceTask}`)).map((entry) => ({ id: entry.id, kind: entry.kind, capabilityId: entry.capabilityId, family: entry.family, ownerFamily: entry.ownerFamily, sourceTask: entry.sourceTask, legacyState: entry.legacyState, state: entry.state, targetImplementationClass: entry.targetImplementationClass })); +assert(candidates.length > 0); +const counts = candidates.reduce((acc, entry) => { acc[entry.legacyState] = (acc[entry.legacyState] ?? 0) + 1; return acc; }, {}); +const behavior = { capability: "RENDER.LIGHTING_FIELDS", operations: ["setCameraProperties", "setLightProperties", "setWorldProperties"], positive: ["field-edit", "undo", "redo", "save-reopen"], negative: ["invalid-camera-range", "missing-data-id"], browser: "chromium", engine: "compiled-WASM-WebEngine-Main", sourceGolden: golden.fixture ?? "M11-02/lighting-field-roundtrip.json" }; +const behaviorHash = digestText(JSON.stringify(behavior)); +const candidate = { schemaVersion: 1, task: "WBV2-P15-001", operation: "LIGHTING_CAPABILITY_CANDIDATE_SELECTION", status: "READY", source: { inventory: inventoryPath, inventorySha256: sha256(inventoryPath), api: sourceApiPath, apiSha256: sha256(sourceApiPath), test: sourceTestPath, testSha256: sha256(sourceTestPath), golden: sourceGoldenPath, goldenSha256: sha256(sourceGoldenPath), strategy: p14StrategyPath, strategySha256: sha256(p14StrategyPath) }, candidate: { capabilityId: "RENDER.LIGHTING_FIELDS", representativeBehavior: behavior, behaviorHash, dedupeKey: `RENDER.LIGHTING_FIELDS|${behaviorHash}|${sha256(sourceApiPath)}|${sha256(sourceTestPath)}`, sourceBacked: true, chromiumProductionReady: true, fullFamilyParity: false }, inventory: { matchedEntries: candidates.length, counts, total: inventory.summary.inventoryEntries, pending: inventory.summary.pendingLegacyEntries, remainderExplicit: true }, entries: candidates, policy: { sourceHistoryReadOnly: true, representativeSliceOnly: true, noRepeatedExecution: true, duplicateValidationAvoided: true, fullHistoricalReproduction: false } }; +const report = { schemaVersion: 1, task: "WBV2-P15-001", operation: "SELECT_LIGHTING_CAPABILITY_BATCH", status: "PASS", candidate: candidate.candidate, inventory: candidate.inventory, source: candidate.source, matchedEntryDigest: digestText(JSON.stringify(candidates)), efficiency: { oneSourceScan: true, existingStrategyReused: true, repeatedBlenderRuns: 0, repeatedChromiumRuns: 0, duplicateValidationAvoided: true }, nextTask: "WBV2-P15-002" }; +if (!write) { process.stdout.write(`wbv2-lighting-selection-ok task=WBV2-P15-001 matched=${candidates.length} capability=RENDER.LIGHTING_FIELDS behaviorHash=${behaviorHash} pending=6618 repeatedRuns=0 next=WBV2-P15-002\n`); process.exit(0); } +fs.mkdirSync(absolute(outputRoot), { recursive: true }); fs.writeFileSync(absolute(candidatePath), `${JSON.stringify(candidate, null, 2)}\n`); fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`); +fs.writeFileSync(absolute(statusPath), `# WBV2-P15-001 status\n\n- task: \`WBV2-P15-001\`; parent: \`WBV2-P15-000\`; status: \`done\`\n- selected capability: \`RENDER.LIGHTING_FIELDS\`; operations: Camera, Light, World fields\n- matched inventory entries: \`${candidates.length}\`; inventory remains \`6900\` total, \`6618\` pending\n- behavior hash: \`${behaviorHash}\`\n- dedupe key binds source API/test hashes; repeated Blender/Chromium runs: \`0\`\n- representative slice: \`true\`; full-family parity: \`false\`\n- nextTask: \`WBV2-P15-002\`\n\nThe candidate is selected from the existing parity map and source/test implementations. Only one unique Camera/Light/World behavior batch will be executed; matching inventory entries remain coverage references, not completion claims.\n`); +const previousPlan = json("tests/golden/WBV2-P15-000/lights-task-plan.json"); const nextPlan = structuredClone(previousPlan); nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P15-000/lights-task-plan.json", sha256: sha256("tests/golden/WBV2-P15-000/lights-task-plan.json") }; nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P15-001" ? { ...task, status: "done", ready: false } : task.id === "WBV2-P15-002" ? { ...task, status: "in_progress", ready: true } : { ...task, ready: false }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P15-002.md"), read("docs/tasks/WBV2-P15-002.md").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-P15-001", "--write"], { cwd: root, stdio: "inherit" }); +const artifactPaths = { parentManifest: parentPath, inventory: inventoryPath, strategy: p14StrategyPath, sourceApi: sourceApiPath, sourceTest: sourceTestPath, sourceGolden: sourceGoldenPath, candidate: candidatePath, report: reportPath, generator: "tools/web/generate-wbv2-lighting-selection.mjs", 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-P15-001", parentTask: "WBV2-P15-000", operation: "SELECT_LIGHTING_CAPABILITY_BATCH", status: "done", enablingTask: true, parityStateChange: false, runtime: "READ_ONLY_SOURCE_CANDIDATE_SELECTION", artifacts, assertions: { capability: "RENDER.LIGHTING_FIELDS", matchedInventoryEntries: candidates.length, inventoryTotal: 6900, inventoryPending: 6618, sourceApiBound: true, chromiumTestBound: true, representativeSliceOnly: true, fullFamilyParity: false, repeatedBlenderRuns: 0, repeatedChromiumRuns: 0, duplicateValidationAvoided: true, deterministic: true, historicalReproduction: false }, nextTask: "WBV2-P15-002" }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); +let queue = read("docs/EXECUTION_QUEUE.md"); queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P15-002` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P15-001/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P15-002.md`](tasks/WBV2-P15-002.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTask = read("nextTask.md"); nextTask = nextTask.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P15-002` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P15-001/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P15-002.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P15-003` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-lighting-fields-production.spec.ts` |"); fs.writeFileSync(absolute("nextTask.md"), nextTask); +process.stdout.write(`wbv2-lighting-selection-written task=WBV2-P15-001 matched=${candidates.length} capability=RENDER.LIGHTING_FIELDS behaviorHash=${behaviorHash} pending=6618 next=WBV2-P15-002 artifacts=${Object.keys(artifacts).length}\n`); diff --git a/tools/web/generate-wbv2-lights-root.mjs b/tools/web/generate-wbv2-lights-root.mjs new file mode 100644 index 000000000..8fe98669c --- /dev/null +++ b/tools/web/generate-wbv2-lights-root.mjs @@ -0,0 +1,53 @@ +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 json = (file) => JSON.parse(read(file)); +const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); +const p14ManifestPath = "tests/golden/WBV2-P14-003/manifest.json"; +const p14ReportPath = "tests/golden/WBV2-P14-003/inventory-coverage-gate-report.json"; +const p14StatusPath = "docs/status/WBV2-P14-003.md"; +const p15Root = "tests/golden/WBV2-P15-000"; +const planPath = `${p15Root}/lights-task-plan.json`; +const reportPath = `${p15Root}/lights-root-report.json`; +const manifestPath = `${p15Root}/manifest.json`; +const statusPath = "docs/status/WBV2-P15-000.md"; +const sourceMapPath = "tests/golden/WBV2-P0-002/parity-map.json"; +const sourceTestPath = "web/tests/e2e/lighting-field-roundtrip.spec.ts"; +const sourceCommandPath = "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp"; + +const p14 = json(p14ManifestPath); const p14Report = json(p14ReportPath); const sourceMap = json(sourceMapPath); +assert.equal(p14.task, "WBV2-P14-003"); assert.equal(p14.status, "done"); assert.equal(p14.nextTask, null); assert.equal(p14Report.status, "PASS"); assert.equal(p14Report.decision.inventoryPending, 6618); assert.equal(sourceMap.summary.inventoryEntries, 6900); +for (const artifact of Object.values(p14.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); +const tasks = [ + { id: "WBV2-P15-000", phase: "P15", title: "authorize_lighting_capability_continuation", kind: "enabling", owner: "PROGRAM", dependsOn: ["WBV2-P14-003"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p15-governance", gate: "G2", card: "docs/tasks/WBV2-P15-000.md", behavior: "Authorize a source-backed Lighting/Camera/World capability slice without reopening completed batches.", outputs: ["continuation root", "candidate scope", "hash boundary"], acceptance: ["P14 coverage remains hash-bound", "source command and Chromium test exist", "one production task is active"], status: "done", ready: false, queueMutationAllowed: true }, + { id: "WBV2-P15-001", phase: "P15", title: "select_lighting_capability_batch", kind: "enabling", owner: "PARITY", dependsOn: ["WBV2-P15-000"], parityId: "RENDER.LIGHTING_FIELDS", implementationClass: "LOCAL_BOUNDED", parallelGroup: "p15-selection", gate: "G2", card: "docs/tasks/WBV2-P15-001.md", behavior: "Select one deterministic Lighting/Camera/World behavior batch from existing source and tests.", outputs: ["candidate report", "behavior hash", "dedupe key"], acceptance: ["source API is present", "Chromium test is present", "candidate remains representative rather than full-family completion"], status: "in_progress", ready: true, queueMutationAllowed: false }, + { id: "WBV2-P15-002", phase: "P15", title: "lighting_fields_engine_receipt", kind: "feature", owner: "RENDER", dependsOn: ["WBV2-P15-001"], parityId: "RENDER.LIGHTING_FIELDS", implementationClass: "LOCAL_EXACT", parallelGroup: "p15-lighting", gate: "G2", card: "docs/tasks/WBV2-P15-002.md", behavior: "Bind Camera, Light, and World field edits, undo/redo, and exact save/reopen to compiled WASM Main in Chromium.", outputs: ["lighting production report", "lighting receipt", "manifest"], acceptance: ["camera/light/world fields match", "undo/redo revisions are sequential", "save/reopen is exact", "malformed values fail closed"], status: "planned", ready: false, queueMutationAllowed: false }, + { id: "WBV2-P15-003", phase: "P15", title: "close_lighting_capability_gate", kind: "enabling", owner: "RELEASE", dependsOn: ["WBV2-P15-002"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p15-release", gate: "G5", card: "docs/tasks/WBV2-P15-003.md", behavior: "Close the Lighting capability gate while preserving partial-family and 6900-entry limitations.", outputs: ["lighting gate", "limited declaration", "manifest"], acceptance: ["only the tested slice is claimed", "inventory remainder remains 6618", "no repeated validation or historical over-claim"], status: "planned", ready: false, queueMutationAllowed: false }, +]; +const plan = { schemaVersion: 1, planId: "BLENDER_WEB_PARITY_V2_LIGHTING_EPOCH_1", status: "ACTIVE_LIGHTING_QUEUE", authority: "queue_reactivated_after_p14_coverage_gate", sourcePlan: "docs/BLENDER_WEB_PARITY_TASK_PLAN_V2.json", executionPointer: "docs/EXECUTION_QUEUE.md", runtimePolicy: { blenderSource: "blender-5.2.0", browserEvidence: ["chromium"], forbiddenBrowsers: ["firefox", "webkit"], mainAuthority: "blender_main", reusePolicy: "source_hash_and_behavior_hash_deduplication" }, parentCoverage: { manifest: p14ManifestPath, report: p14ReportPath, inventoryTotal: 6900, inventoryPending: 6618, duplicateValidationAvoided: true }, tasks }; +fs.mkdirSync(absolute(p15Root), { recursive: true }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(plan, null, 2)}\n`); +const report = { schemaVersion: 1, task: "WBV2-P15-000", operation: "AUTHORIZE_LIGHTING_CAPABILITY_CONTINUATION", status: "PASS", parent: { task: p14.task, manifest: p14ManifestPath, manifestSha256: sha256(p14ManifestPath), report: p14ReportPath, reportSha256: sha256(p14ReportPath), previousDecision: p14Report.decision.status }, continuation: { root: "WBV2-P15-000", firstTask: "WBV2-P15-001", plannedTasks: 4, candidate: "RENDER.LIGHTING_FIELDS", sourceApi: sourceCommandPath, chromiumTest: sourceTestPath, browser: "chromium", inventoryTotal: 6900, inventoryPending: 6618, noRepeatedExecution: true }, policy: { p14EvidencePreserved: true, sourceHistoryReadOnly: true, representativeSliceOnly: true, duplicateValidationAvoided: true, authorizedRebaselineOnly: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P15-001" }; +fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`); +fs.writeFileSync(absolute("docs/tasks/WBV2-P15-000.md"), `# WBV2-P15-000: lighting capability continuation root\n\n- task: WBV2-P15-000\n- parent: WBV2-P14-003\n- status: done\n- gap: workflow:authorize_lighting_capability_continuation\n- ownerFamily: PROGRAM\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nAuthorize a source-backed Lighting/Camera/World continuation. P15 reuses the 6900-entry coverage ledger and runs only one representative Chromium production slice for fields already exposed by the compiled WebEngine API.\n\n## 验收\n\n- \`node tools/web/generate-wbv2-lights-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-P15-000/\`\n- Manifest: \`tests/golden/WBV2-P15-000/manifest.json\`\n- Rollback: restore P14-003 as queue parent without rewriting P14 evidence.\n`); +const cards = { + "WBV2-P15-001": `# WBV2-P15-001: select_lighting_capability_batch\n\n- task: WBV2-P15-001\n- parent: WBV2-P15-000\n- status: in_progress\n- gap: capability:RENDER.LIGHTING_FIELDS\n- ownerFamily: PARITY\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nSelect one deterministic Camera, Light, and World field behavior batch from the existing source API and Chromium test.\n\n## 输入与范围\n\n- Focused source: \`blender-5.2.0/source/blender/web_engine/web_engine_api.cpp\`\n- Existing production test: \`web/tests/e2e/lighting-field-roundtrip.spec.ts\`\n- Inventory: \`tests/golden/WBV2-P0-002/parity-map.json\`\n- Production entrypoint: \`node tools/web/generate-wbv2-lighting-selection.mjs --write\`\n\n## 验收\n\n- source API and Chromium test hashes are bound\n- one behavior hash covers camera/light/world fields\n- representative slice is not promoted to full-family parity\n- malformed, hash-drift, unsupported, or false-completion input keeps in_progress\n- \`node tools/web/check-task-context.mjs --task WBV2-P15-001 --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P15-001/\`\n- Status: \`docs/status/WBV2-P15-001.md\`\n- Manifest: \`tests/golden/WBV2-P15-001/manifest.json\`\n- Rollback: restore P15-000 as queue parent.\n`, + "WBV2-P15-002": `# WBV2-P15-002: lighting_fields_engine_receipt\n\n- task: WBV2-P15-002\n- parent: WBV2-P15-001\n- status: planned\n- gap: capability:RENDER.LIGHTING_FIELDS\n- ownerFamily: RENDER\n- targetImplementationClass: LOCAL_EXACT\n\n## 目标\n\nBind Camera, Light, and World edits, undo/redo, and exact save/reopen to the compiled WASM Main in Chromium.\n\n## 输入与范围\n\n- Focused source: \`tests/golden/WBV2-P15-001/lighting-selection-report.json\`\n- Production test: \`web/tests/e2e/wbv2-lighting-fields-production.spec.ts\`\n- Production entrypoint: \`npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-lighting-fields-production.spec.ts\`\n\n## 验收\n\n- camera/light/world fields match the bounded expected values\n- undo/redo revisions are sequential\n- save/reopen is exact\n- malformed values fail closed without Main mutation\n- Chromium is the only browser\n- \`node tools/web/check-task-context.mjs --task WBV2-P15-002 --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P15-002/\`\n- Status: \`docs/status/WBV2-P15-002.md\`\n- Manifest: \`tests/golden/WBV2-P15-002/manifest.json\`\n- Rollback: restore P15-001 as queue parent.\n`, + "WBV2-P15-003": `# WBV2-P15-003: close_lighting_capability_gate\n\n- task: WBV2-P15-003\n- parent: WBV2-P15-002\n- status: planned\n- gap: workflow:close_lighting_capability_gate\n- ownerFamily: RELEASE\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nClose the Lighting capability gate while preserving partial-family and 6900-entry limitations.\n\n## 输入与范围\n\n- Focused receipt: \`tests/golden/WBV2-P15-002/lighting-fields-receipt-report.json\`\n- Coverage matrix: \`tests/golden/WBV2-P14-002/capability-evidence-matrix.json\`\n- Production entrypoint: \`node tools/web/generate-wbv2-lighting-gate.mjs --write\`\n\n## 验收\n\n- only the tested lighting slice is claimed\n- pending inventory remains 6618\n- duplicate validation remains zero\n- historical reproduction remains false\n- \`node tools/web/check-task-context.mjs --task WBV2-P15-003 --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P15-003/\`\n- Status: \`docs/status/WBV2-P15-003.md\`\n- Manifest: \`tests/golden/WBV2-P15-003/manifest.json\`\n- Rollback: restore P15-002 as queue parent.\n`, +}; +for (const [id, card] of Object.entries(cards)) fs.writeFileSync(absolute(`docs/tasks/${id}.md`), `${card}\n`); +fs.writeFileSync(absolute(statusPath), `# WBV2-P15-000 status\n\n- task: \`WBV2-P15-000\`; parent: \`WBV2-P14-003\`; status: \`done\`\n- candidate: \`RENDER.LIGHTING_FIELDS\`; source API and Chromium test are present\n- inventory carried forward: \`6900\` total, \`6618\` pending\n- duplicate validation: \`forbidden\`; representative slice only\n- nextTask: \`WBV2-P15-001\`\n\nP15 is an authorized continuation that reuses the P14 coverage ledger and validates one source-backed Camera/Light/World behavior batch in Chromium.\n`); +const artifactPaths = { parentManifest: p14ManifestPath, parentReport: p14ReportPath, sourceMap: sourceMapPath, sourceApi: sourceCommandPath, sourceTest: sourceTestPath, plan: planPath, report: reportPath, rootCard: "docs/tasks/WBV2-P15-000.md", rootStatus: statusPath }; +const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }])); +const manifest = { schemaVersion: 1, task: "WBV2-P15-000", parentTask: "WBV2-P14-003", operation: "AUTHORIZE_LIGHTING_CAPABILITY_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, runtime: "READ_ONLY_LIGHTING_CONTINUATION_ROOT", artifacts, assertions: { p14EvidencePreserved: true, sourceApiBound: true, chromiumTestBound: true, inventoryTotal: 6900, inventoryPending: 6618, duplicateValidationAvoided: true, representativeSliceOnly: true, authorizedRebaselineOnly: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P15-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-P15-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P15-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P15-001.md`](tasks/WBV2-P15-001.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); +let nextTask = read("nextTask.md"); nextTask = nextTask.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P15-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P15-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P15-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P15-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-lighting-selection.mjs --write` |"); fs.writeFileSync(absolute("nextTask.md"), nextTask); +process.stdout.write("wbv2-lights-root-written root=WBV2-P15-000 next=WBV2-P15-001 candidate=RENDER.LIGHTING_FIELDS inventoryPending=6618\n"); diff --git a/web/tests/e2e/wbv2-lighting-fields-production.spec.ts b/web/tests/e2e/wbv2-lighting-fields-production.spec.ts new file mode 100644 index 000000000..c9fcec9ab --- /dev/null +++ b/web/tests/e2e/wbv2-lighting-fields-production.spec.ts @@ -0,0 +1,59 @@ +import { expect, test } from "@playwright/test"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; + +const root = path.resolve(import.meta.dirname, "../../.."); +const evidenceRoot = path.join(root, "tests/golden/WBV2-P15-002"); +const fixturePath = path.join(root, "tests/files/web/basic_scene.blend"); +const fixture = fs.readFileSync(fixturePath); +const fixtureSha256 = crypto.createHash("sha256").update(fixture).digest("hex"); +const expected = JSON.parse(fs.readFileSync(path.join(root, "tests/golden/M11-02/lighting-field-roundtrip.json"), "utf8")); + +function close(actual: unknown, expectedValue: unknown, tolerance = 1e-5): void { + if (typeof expectedValue === "number") { expect(actual as number).toBeCloseTo(expectedValue, Math.max(0, Math.ceil(-Math.log10(tolerance)))); return; } + if (Array.isArray(expectedValue)) { expect(actual).toHaveLength(expectedValue.length); expectedValue.forEach((value, index) => close((actual as unknown[])[index], value, tolerance)); return; } + if (expectedValue && typeof expectedValue === "object") { for (const [key, value] of Object.entries(expectedValue)) close((actual as Record)[key], value, tolerance); return; } + expect(actual).toEqual(expectedValue); +} + +test("WBV2-P15-002 binds camera, light, and world fields to compiled WASM Main", async ({ page }) => { + test.setTimeout(120_000); + await page.goto("/"); + const result = await page.evaluate(async (bytes) => { + const { WebEngineClient } = await import("/src/engine-client/WebEngineClient.ts"); + const client = new WebEngineClient({ timeoutMs: 30_000 }); + const reopened = new WebEngineClient({ timeoutMs: 30_000 }); + const digest = async (value: ArrayBuffer): Promise => { const hash = await crypto.subtle.digest("SHA-256", value); return Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join(""); }; + try { + const opened = await client.openBlend(Uint8Array.from(bytes).buffer); + const camera = opened.snapshot.cameras.find((item) => item.id === "camera:Camera.001")!; + const light = opened.snapshot.lights.find((item) => item.id === "light:Area")!; + const world = opened.snapshot.worlds.find((item) => item.id === "world:World")!; + const beforeRevision = opened.snapshot.revision; + const cameraEdit = await client.applyCommand({ type: "setCameraProperties", dataId: camera.id, properties: { lensMm: 35, sensorWidthMm: 32, sensorHeightMm: 18, sensorFit: 2, shift: [0.1, -0.2], near: 0.2, far: 500, orthoScale: 8, depthOfField: { enabled: true, focusDistance: 4.5, apertureFStop: 1.8, apertureBlades: 7, apertureRotation: 0.25, apertureRatio: 1.2 } } } as any); + const cameraUndo = await client.applyCommand({ type: "undo" }); + const cameraRedo = await client.applyCommand({ type: "redo" }); + const lightEdit = await client.applyCommand({ type: "setLightProperties", dataId: light.id, properties: { color: [0.25, 0.5, 0.75], energy: 400, exposure: 1, temperature: 5000, useTemperature: true, castsShadow: false, radius: 0.3, spotAngle: 1.1, spotBlend: 0.25, areaSize: 3, areaSizeY: 2, areaSpread: 2.4, sunAngle: 0.1 } } as any); + const lightUndo = await client.applyCommand({ type: "undo" }); + const lightRedo = await client.applyCommand({ type: "redo" }); + const worldEdit = await client.applyCommand({ type: "setWorldProperties", dataId: world.id, properties: { color: [0.1, 0.2, 0.3], exposure: 0.5, mist: { enabled: true, type: "LINEAR", start: 2, depth: 50, intensity: 0.2, height: 3 } } } as any); + const worldUndo = await client.applyCommand({ type: "undo" }); + const worldRedo = await client.applyCommand({ type: "redo" }); + const beforeMalformed = (await client.snapshot()).snapshot; + const malformed = await client.applyCommand({ type: "setCameraProperties", dataId: camera.id, properties: { near: 10, far: 1 } } as any).then(() => ({ code: "NO_ERROR" })).catch((error: any) => ({ code: error?.code, message: error?.message })); + const afterMalformed = (await client.snapshot()).snapshot; + const saved = await client.saveBlend(); + const reopenedResult = await reopened.openBlend(saved); + return { browser: "chromium", sourceSha256: await digest(Uint8Array.from(bytes).buffer), beforeRevision, revisions: [beforeRevision, cameraEdit.snapshot.revision, cameraUndo.snapshot.revision, cameraRedo.snapshot.revision, lightEdit.snapshot.revision, lightUndo.snapshot.revision, lightRedo.snapshot.revision, worldEdit.snapshot.revision, worldUndo.snapshot.revision, worldRedo.snapshot.revision], malformed, malformedRevisionPreserved: afterMalformed.revision === beforeMalformed.revision, camera: reopenedResult.snapshot.cameras.find((item) => item.id === camera.id), light: reopenedResult.snapshot.lights.find((item) => item.id === light.id), world: reopenedResult.snapshot.worlds.find((item) => item.id === world.id), reopenedRevision: reopenedResult.snapshot.revision, savedSha256: await digest(saved) }; + } finally { client.terminate(); reopened.terminate(); } + }, Array.from(fixture)); + + fs.mkdirSync(evidenceRoot, { recursive: true }); + const output = process.env.WBV2_LIGHTING_REPORT ?? "lighting-fields-production.json"; + fs.writeFileSync(path.join(evidenceRoot, output), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P15-002", operation: "LIGHTING_FIELDS_ENGINE_CHROMIUM", queueMutation: false, ...result }, null, 2)}\n`); + expect(result.browser).toBe("chromium"); expect(result.sourceSha256).toBe(fixtureSha256); expect(result.revisions).toEqual(result.revisions.map((_, index) => result.beforeRevision + index)); expect(result.malformed.code).not.toBe("NO_ERROR"); expect(result.malformedRevisionPreserved).toBe(true); + close(result.camera, Object.fromEntries(Object.entries(expected.camera).filter(([key]) => !key.startsWith("viewport")))); + close(result.light, Object.fromEntries(Object.entries(expected.light).filter(([key]) => !key.startsWith("viewport")))); + close(result.world, expected.world); +});