From 8569a35130934938ce4949572ec84a8c359cbfa6 Mon Sep 17 00:00:00 2001 From: mes123456 Date: Fri, 4 Sep 2026 16:37:25 +0800 Subject: [PATCH] fix(web): recover and parameterize mesh operator batches --- my-tools/authorize_next_wbv2_task.py | 53 +++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/my-tools/authorize_next_wbv2_task.py b/my-tools/authorize_next_wbv2_task.py index dfd840a2d..14b3ec910 100644 --- a/my-tools/authorize_next_wbv2_task.py +++ b/my-tools/authorize_next_wbv2_task.py @@ -24,6 +24,42 @@ AUTO_PLANNER_STATUS = CONTROL_ROOT / "auto-planner.json" PREFERRED_BATCHES = [ + { + "moduleId": "MESH_BEVEL_OPERATOR_BATCH", + "title": "verify mesh bevel operator through native Main", + "owner": "MESH", + "identifiers": ["MESH_OT_bevel"], + "rna": [], + "fixture": "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", + "test": "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", + "production": "tests/golden/{task}/mesh-topology-production.json", + "types": [], + "batchOperation": "BEVEL", + }, + { + "moduleId": "MESH_INSET_OPERATOR_BATCH", + "title": "verify mesh inset operator through native Main", + "owner": "MESH", + "identifiers": ["MESH_OT_inset"], + "rna": [], + "fixture": "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", + "test": "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", + "production": "tests/golden/{task}/mesh-topology-production.json", + "types": [], + "batchOperation": "INSET", + }, + { + "moduleId": "MESH_LOOPCUT_OPERATOR_BATCH", + "title": "verify mesh loop cut operator through native Main", + "owner": "MESH", + "identifiers": ["MESH_OT_loopcut"], + "rna": [], + "fixture": "tests/files/web/generated/WBV2-P2-003-MESH.EDIT_CORE.blend", + "test": "web/tests/e2e/wbv2-mesh-topology-production.spec.ts", + "production": "tests/golden/{task}/mesh-topology-production.json", + "types": [], + "batchOperation": "LOOP_CUT", + }, { "moduleId": "OBJECT_TRANSFORM_APPLY_OPERATOR_BATCH", "title": "verify object transform apply operator through native Main", @@ -632,6 +668,20 @@ def recover_blocked_native_batch(current: str, index: dict, plan: dict, inventor receipt_path = ROOT / "tests/golden" / current / "module-receipt.json" receipt = read_json(receipt_path) if receipt_path.is_file() else {} if not isinstance(module, dict) or not str(module.get("moduleId", "")).startswith(("AUTO_COMPOSITOR_NATIVE_NODE_READER", "AUTO_SHADER_NATIVE_NODE_READER")): + if isinstance(module, dict) and str(module.get("moduleId", "")).startswith("MESH_") and receipt.get("status") == "BLOCKED" and module.get("commands"): + operation = { + "MESH_BEVEL_OPERATOR_BATCH": "BEVEL", + "MESH_INSET_OPERATOR_BATCH": "INSET", + "MESH_LOOPCUT_OPERATOR_BATCH": "LOOP_CUT", + }.get(str(module.get("moduleId"))) + command = module["commands"][-1] + if operation and "WBV2_BATCH_OPERATION=" not in command: + module["commands"][-1] = command.replace("WBV2_BATCH_TYPES=", f"WBV2_BATCH_OPERATION={operation} WBV2_BATCH_TYPES=", 1) + write_json(ROOT / index["source"]["path"], plan) + run_node("tools/web/generate-v2-task-index.mjs", "--plan-path", index["source"]["path"]) + run_node("tools/web/check-task-context.mjs", "--task", current, "--write") + print(f"wbv2-blocked-mesh-batch-recovered task={current} operation={operation}") + return True return False if receipt.get("status") != "BLOCKED": return False @@ -1086,6 +1136,7 @@ def main() -> int: else: fixture_env = f"WBV2_BATCH_FIXTURE={batch['fixture']}" production_env = f"WBV2_BATCH_PRODUCTION={batch['production'].format(task=module_task)}" + operation_env = f"WBV2_BATCH_OPERATION={batch['batchOperation']}" if batch.get("batchOperation") else "" if batch.get("dependencyReuse"): commands = [f"node tools/web/reuse-wbv2-source-dependencies.mjs --task {module_task} --write"] else: @@ -1093,7 +1144,7 @@ def main() -> int: "source tools/web/emscripten-env.sh && cmake --build build_web_blender6 --target web_engine -- -j8 && cp build_web_blender6/bin/web_engine.wasm web/app/src/vendor/blender/web_engine.wasm && cp build_web_blender6/bin/web_engine.wasm web/app/public/vendor/blender/web_engine.wasm && node tools/web/split-wbv2-wasm.mjs --input web/app/public/vendor/blender/web_engine.wasm --output-dir web/app/public/vendor/blender/modules/single --split-funcs web_engine_get_live_handles && node tools/web/split-wbv2-wasm.mjs --input web/app/public/vendor/blender/pthread/web_engine.wasm --output-dir web/app/public/vendor/blender/modules/pthread --split-funcs web_engine_get_live_handles", "npm --prefix web run typecheck", "npm --prefix web run build", - f"WBV2_BATCH_TASK={module_task} {production_env} {fixture_env} WBV2_BATCH_TYPES='{batch_types}' WBV2_BATCH_UNITS='{batch_units}' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/{Path(batch['test']).name}", + f"WBV2_BATCH_TASK={module_task} {production_env} {fixture_env} {operation_env} WBV2_BATCH_TYPES='{batch_types}' WBV2_BATCH_UNITS='{batch_units}' WEB_TEST_PORT=5371 npm --prefix web run test:e2e -- --workers=1 tests/e2e/{Path(batch['test']).name}", ] root_record = {"id": root_task, "phase": str(phase), "title": "authorize_modifier_reader_batch", "kind": "enabling", "owner": "PROGRAM", "dependsOn": [current], "parityId": None, "implementationClass": "QUEUE_ONLY", "parallelGroup": f"module-root-{phase}", "gate": "MODULE", "card": f"docs/tasks/{root_task}.md", "behavior": "Authorize one shared source-backed modifier reader batch.", "outputs": ["successor authorization", "module plan", "manifest", "status"], "acceptance": ["prior evidence remains hash-bound", "batch source mapping is explicit", "inventory remains source-derived"], "commands": ["node tools/web/check-execution-control-plane.mjs"], "status": "done", "ready": False, "queueMutationAllowed": True} module_record = {"id": module_task, "phase": str(phase), "title": batch["title"], "kind": "module", "owner": batch["owner"], "dependsOn": [root_task], "parityId": batch["moduleId"], "implementationClass": "LOCAL_EXACT", "parallelGroup": f"module-{batch['moduleId'].lower()}", "gate": "MODULE", "card": f"docs/tasks/{module_task}.md", "behavior": f"Verify the {batch['moduleId']} batch through Blender Main, WASM and Chromium recovery.", "outputs": ["aggregate module receipt", "coverage bindings", "manifest", "status"], "acceptance": ["source and protocol hashes are bound", "every selected Main reader type is proven", "negative no-mutation and recovery are proven", "Chromium and save/reopen evidence are exact"], "status": "in_progress", "ready": True, "queueMutationAllowed": True, "batchId": contract["batchId"], "selectedRecordIds": contract["selectedRecordIds"], "module": {"moduleId": batch["moduleId"], "batchId": contract["batchId"], "selectedRecordIds": contract["selectedRecordIds"], "sourceBacked": True, "capabilities": [f"CAP-{batch['moduleId']}-READER", f"CAP-{batch['moduleId']}-RECOVERY", f"CAP-{batch['moduleId']}-FAIL-CLOSED"], "sourcePaths": source_paths, "reuseReceipts": batch.get("reuseReceipts", [{"manifest": "tests/golden/WBV2-P1107-000/manifest.json", "report": "tests/golden/WBV2-P1107-000/module-receipt.json"}]), "dependencyReuse": batch.get("dependencyReuse", []), "positive": [f"{name} type is read from Blender Main" for name in batch["identifiers"]] + ["shared RNA metadata is preserved", "save/reopen preserves the batch metadata"], "negative": ["malformed blend is rejected without Main mutation", "unsupported batch data fails closed", "non-finite metadata is not synthesized"], "recovery": ["save/reopen", "worker termination", "deterministic second read"], "commands": commands, "fullFamilyParity": False, "evidencePaths": [batch["production"].format(task=module_task)], "coverageBindings": contract["selectedRecordIds"]}}