Advance deduplicated transform apply coverage
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-08-28 18:17:17 +08:00
parent 3ab47ae2e9
commit 0bd8419ae3
39 changed files with 2226 additions and 19 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,48 @@
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 abs = (file) => path.join(root, file);
const read = (file) => fs.readFileSync(abs(file), "utf8");
const json = (file) => JSON.parse(read(file));
const sha = (file) => crypto.createHash("sha256").update(fs.readFileSync(abs(file))).digest("hex");
const p22Path = "tests/golden/WBV2-P22-003/manifest.json";
const p22ReportPath = "tests/golden/WBV2-P22-003/object-delete-gate-report.json";
const out = "tests/golden/WBV2-P23-000";
const planPath = `${out}/transform-task-plan.json`;
const reportPath = `${out}/transform-root-report.json`;
const manifestPath = `${out}/manifest.json`;
const statusPath = "docs/status/WBV2-P23-000.md";
const inventoryPath = "tests/golden/WBV2-P0-002/parity-map.json";
const apiPath = "blender-5.2.0/source/blender/web_engine/web_engine_api.cpp";
const clientPath = "web/app/src/engine-client/WebEngineClient.ts";
const p22 = json(p22Path);
const p22Report = json(p22ReportPath);
const inventory = json(inventoryPath);
assert.equal(p22.status, "done");
assert.ok(p22.nextTask === null || p22.nextTask === "WBV2-P23-000");
assert.equal(p22Report.status, "PASS");
assert.equal(p22Report.decision.effectivePending, 6610);
assert.equal(inventory.summary.inventoryEntries, 6900);
for (const artifact of Object.values(p22.artifacts ?? {})) assert.equal(sha(artifact.path), artifact.sha256, artifact.path);
assert.match(read(apiPath), /applyObjectTransform/);
assert.match(read(clientPath), /applyCommand/);
const task = (id, title, owner, parent, status, ready, behavior) => ({ id, phase: "P23", title, kind: id.endsWith("000") || id.endsWith("003") ? "enabling" : id.endsWith("001") ? "enabling" : "feature", owner, dependsOn: [parent], parityId: id.endsWith("001") || id.endsWith("002") ? "OBJECT_OPERATIONS.TRANSFORM_APPLY" : null, implementationClass: id.endsWith("002") ? "LOCAL_EXACT" : "LOCAL_BOUNDED", parallelGroup: `p23-${id.slice(-3)}`, gate: id.endsWith("003") ? "G5" : "G2", card: `docs/tasks/${id}.md`, behavior, outputs: ["report", "receipt", "manifest"], acceptance: ["source and evidence hashes are bound", "unique behavior is verified once", "save/reopen remains exact", "malformed input fails closed"], status, ready, queueMutationAllowed: id.endsWith("000") });
const tasks = [task("WBV2-P23-000", "authorize_object_transform_apply_continuation", "PROGRAM", "WBV2-P22-003", "done", false, "Authorize one Object Transform Apply behavior after the P22 delete overlay."), task("WBV2-P23-001", "select_object_transform_apply_batch", "PARITY", "WBV2-P23-000", "in_progress", true, "Select applyObjectTransform as one unique Object Operations behavior."), task("WBV2-P23-002", "object_transform_apply_engine_receipt", "OBJECT", "WBV2-P23-001", "planned", false, "Bind applyObjectTransform, undo/redo, malformed rejection, and exact save/reopen to compiled WASM Main in Chromium."), task("WBV2-P23-003", "close_object_transform_apply_gate", "RELEASE", "WBV2-P23-002", "planned", false, "Close the applyObjectTransform gate and graduate only the exact operator binding.")];
const plan = { schemaVersion: 1, planId: "BLENDER_WEB_PARITY_V2_OBJECT_TRANSFORM_APPLY_EPOCH_1", status: "ACTIVE_OBJECT_TRANSFORM_QUEUE", authority: "queue_reactivated_after_p22_delete_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" }, parentDelete: { manifest: p22Path, report: p22ReportPath, effectivePending: 6610, duplicateValidationAvoided: true }, tasks };
fs.mkdirSync(abs(out), { recursive: true }); fs.writeFileSync(abs(planPath), `${JSON.stringify(plan, null, 2)}\n`);
const report = { schemaVersion: 1, task: "WBV2-P23-000", operation: "AUTHORIZE_OBJECT_TRANSFORM_APPLY_CONTINUATION", status: "PASS", parent: { task: p22.task, manifest: p22Path, manifestSha256: sha(p22Path), report: p22ReportPath, reportSha256: sha(p22ReportPath), previousDecision: p22Report.decision.status, effectivePending: 6610 }, continuation: { root: "WBV2-P23-000", firstTask: "WBV2-P23-001", plannedTasks: 4, candidate: "OBJECT_OPERATIONS.TRANSFORM_APPLY", sourceApi: apiPath, browser: "chromium", noRepeatedExecution: true }, policy: { p22EvidencePreserved: true, sourceHistoryReadOnly: true, representativeSliceOnly: true, duplicateValidationAvoided: true, authorizedRebaselineOnly: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P23-001" };
fs.writeFileSync(abs(reportPath), `${JSON.stringify(report, null, 2)}\n`);
const cards = { "WBV2-P23-000": `# WBV2-P23-000: object transform continuation root\n\n- task: WBV2-P23-000\n- parent: WBV2-P22-003\n- status: done\n- gap: workflow:authorize_object_transform_apply_continuation\n- ownerFamily: PROGRAM\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nAuthorize one source-backed Object Transform Apply behavior after the P22 delete overlay.\n\n## 验收\n\n- \`node tools/web/generate-wbv2-transform-root.mjs\`\n- \`node tools/web/check-execution-control-plane.mjs\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P23-000/\`\n- Manifest: \`tests/golden/WBV2-P23-000/manifest.json\`\n- Rollback: restore P22-003 as queue parent.\n`, "WBV2-P23-001": `# WBV2-P23-001: select_object_transform_apply_batch\n\n- task: WBV2-P23-001\n- parent: WBV2-P23-000\n- status: in_progress\n- gap: capability:OBJECT_OPERATIONS.TRANSFORM_APPLY\n- ownerFamily: PARITY\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nSelect applyObjectTransform as one unique Object Operations behavior.\n\n## 输入与范围\n\n- Focused source: \`blender-5.2.0/source/blender/web_engine/web_engine_api.cpp\`\n- Existing client: \`web/app/src/engine-client/WebEngineClient.ts\`\n- Inventory: \`tests/golden/WBV2-P0-002/parity-map.json\`\n- Production entrypoint: \`node tools/web/generate-wbv2-transform-selection.mjs --write\`\n\n## 验收\n\n- source command is hash-bound\n- prior object evidence is not rerun\n- one legacy operator binding is selected\n- malformed, hash-drift, unsupported, or false-completion input keeps in_progress\n- \`node tools/web/check-task-context.mjs --task WBV2-P23-001 --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P23-001/\`\n- Status: \`docs/status/WBV2-P23-001.md\`\n- Manifest: \`tests/golden/WBV2-P23-001/manifest.json\`\n- Rollback: restore P23-000 as queue parent.\n`, "WBV2-P23-002": `# WBV2-P23-002: object transform apply engine receipt\n\n- task: WBV2-P23-002\n- parent: WBV2-P23-001\n- status: planned\n- gap: capability:OBJECT_OPERATIONS.TRANSFORM_APPLY\n- ownerFamily: OBJECT\n- targetImplementationClass: LOCAL_EXACT\n\n## 目标\n\nBind applyObjectTransform, undo/redo, malformed rejection, and exact save/reopen to compiled WASM Main in Chromium.\n\n## 输入与范围\n\n- Focused source: \`tests/golden/WBV2-P23-001/object-transform-selection-report.json\`\n- Production test: \`web/tests/e2e/wbv2-object-transform-production.spec.ts\`\n- Production entrypoint: \`npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-object-transform-production.spec.ts\`\n\n## 验收\n\n- transform is applied\n- undo/redo revisions are sequential\n- malformed transform fails closed without Main mutation\n- save/reopen is exact and deterministic\n- Chromium is the only browser\n- malformed, hash-drift, unsupported, or false-completion input keeps in_progress\n- \`node tools/web/check-task-context.mjs --task WBV2-P23-002 --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P23-002/\`\n- Status: \`docs/status/WBV2-P23-002.md\`\n- Manifest: \`tests/golden/WBV2-P23-002/manifest.json\`\n- Rollback: restore P23-001 as queue parent.\n`, "WBV2-P23-003": `# WBV2-P23-003: close object transform apply gate\n\n- task: WBV2-P23-003\n- parent: WBV2-P23-002\n- status: planned\n- gap: workflow:close_object_transform_apply_gate\n- ownerFamily: RELEASE\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nClose the applyObjectTransform gate and graduate only the exact operator binding.\n\n## 输入与范围\n\n- Focused receipt: \`tests/golden/WBV2-P23-002/object-transform-receipt-report.json\`\n- Previous overlay: \`tests/golden/WBV2-P22-003/inventory-completion-overlay.json\`\n- Production entrypoint: \`node tools/web/generate-wbv2-transform-gate.mjs --write\`\n\n## 验收\n\n- only object transform apply is claimed\n- effective inventory remains explicit\n- duplicate validation remains zero\n- malformed, hash-drift, unsupported, or false-completion input keeps in_progress\n- historical reproduction remains false\n- \`node tools/web/check-task-context.mjs --task WBV2-P23-003 --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P23-003/\`\n- Status: \`docs/status/WBV2-P23-003.md\`\n- Manifest: \`tests/golden/WBV2-P23-003/manifest.json\`\n- Rollback: restore P23-002 as queue parent.\n` };
for (const [id, card] of Object.entries(cards)) fs.writeFileSync(abs(`docs/tasks/${id}.md`), card);
fs.writeFileSync(abs(statusPath), "# WBV2-P23-000 status\n\n- task: `WBV2-P23-000`; parent: `WBV2-P22-003`; status: `done`\n- candidate: `OBJECT_OPERATIONS.TRANSFORM_APPLY`; source API is present\n- effective inventory carried forward: `289` completed, `6610` pending\n- duplicate validation: `forbidden`; representative slice only\n- nextTask: `WBV2-P23-001`\n");
p22Report.nextTask = "WBV2-P23-000"; p22Report.policy = { ...(p22Report.policy ?? {}), terminalQueuePointer: false, authorizedContinuation: "WBV2-P23-000" }; fs.writeFileSync(abs(p22ReportPath), `${JSON.stringify(p22Report, null, 2)}\n`); p22.nextTask = "WBV2-P23-000"; p22.continuation = { authorized: true, root: "WBV2-P23-000", scope: "OBJECT_OPERATIONS_TRANSFORM_APPLY" }; fs.writeFileSync(abs(p22Path), `${JSON.stringify(p22, null, 2)}\n`); execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", "WBV2-P22-003", "--write"], { cwd: root, stdio: "pipe" }); p22.artifacts = Object.fromEntries(Object.entries(p22.artifacts).map(([name, artifact]) => [name, { ...artifact, sha256: sha(artifact.path) }])); fs.writeFileSync(abs(p22Path), `${JSON.stringify(p22, null, 2)}\n`); report.parent.manifestSha256 = sha(p22Path); report.parent.reportSha256 = sha(p22ReportPath); fs.writeFileSync(abs(reportPath), `${JSON.stringify(report, null, 2)}\n`);
const rootPaths = { parentManifest: p22Path, parentReport: p22ReportPath, inventory: inventoryPath, sourceApi: apiPath, sourceClient: clientPath, plan: planPath, report: reportPath, rootCard: "docs/tasks/WBV2-P23-000.md", rootStatus: statusPath }; const artifacts = Object.fromEntries(Object.entries(rootPaths).map(([name, file]) => [name, { path: file, sha256: sha(file) }])); fs.writeFileSync(abs(manifestPath), `${JSON.stringify({ schemaVersion: 1, task: "WBV2-P23-000", parentTask: "WBV2-P22-003", operation: "AUTHORIZE_OBJECT_TRANSFORM_APPLY_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, runtime: "READ_ONLY_OBJECT_TRANSFORM_CONTINUATION_ROOT", artifacts, assertions: { p22EvidencePreserved: true, sourceApiBound: true, inventoryTotal: 6900, effectiveCompleted: 289, effectivePending: 6610, duplicateValidationAvoided: true, representativeSliceOnly: true, authorizedRebaselineOnly: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P23-001" }, null, 2)}\n`);
execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" }); let queue = read("docs/EXECUTION_QUEUE.md"); queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P23-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P23-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P23-001.md`](tasks/WBV2-P23-001.md) |"); fs.writeFileSync(abs("docs/EXECUTION_QUEUE.md"), queue); let next = read("nextTask.md"); next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P23-001` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P23-000/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P23-001.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P23-002` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-transform-selection.mjs --write` |"); fs.writeFileSync(abs("nextTask.md"), next);
console.log("wbv2-transform-root-written root=WBV2-P23-000 next=WBV2-P23-001 candidate=OBJECT_OPERATIONS.TRANSFORM_APPLY effectivePending=6610");

File diff suppressed because one or more lines are too long