Files
workinf_Blender_Wasm/tools/web/check-wbv2-module-execution.mjs
mes123456 f3e21c6b98
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
chore: checkpoint web Blender migration source, tools and docs
Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer,
web workflow engine and protocol, tooling, docs and task records.
Large generated evidence, user-testing archives, build snapshots and
imported test assets remain untracked.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-11-10 11:18:01 +08:00

154 lines
8.5 KiB
JavaScript

import assert from "node:assert/strict";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
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 exists = (file) => fs.existsSync(abs(file));
const dynamicInventoryPath = "tests/golden/WBV2/dynamic-inventory.json";
const issues = [];
const fail = (code, detail) => issues.push({ code, detail });
const queue = read("docs/EXECUTION_QUEUE.md");
const currentTask = queue.match(/\| 当前任务 \| `([^`]+)` \|/u)?.[1];
const parentPath = queue.match(/\| parent manifest \| `([^`]+)` \|/u)?.[1];
if (!currentTask || !parentPath) fail("QUEUE_POINTER_INVALID", "queue must declare current task and parent manifest");
let index;
let plan;
let parent;
let dynamicInventory;
try {
index = json("tests/golden/WBV2/task-index.json");
plan = json(index.source.path);
parent = json(parentPath);
dynamicInventory = json(dynamicInventoryPath);
} catch (error) {
fail("CONTROL_PLANE_READ_ERROR", error instanceof Error ? error.message : String(error));
}
if (!dynamicInventory || !exists(dynamicInventoryPath)) fail("DYNAMIC_INVENTORY_MISSING", dynamicInventoryPath);
else {
try {
assert.equal(dynamicInventory.schemaVersion, 1);
assert.equal(dynamicInventory.operation, "BLENDER_52_SOURCE_DYNAMIC_INVENTORY");
assert.ok(["SOURCE_DERIVED_UNVERIFIED", "SOURCE_DERIVED_WITH_EXPLICIT_COVERAGE"].includes(dynamicInventory.status));
assert.match(dynamicInventory.authority.sourceTreeSha256, /^[a-f0-9]{64}$/u);
assert.equal(dynamicInventory.policy.hardTarget, false);
assert.equal(dynamicInventory.policy.planningEstimate, 5200);
assert.equal(dynamicInventory.coverage.verifiedUnits + dynamicInventory.coverage.unverifiedUnits, dynamicInventory.summary.unitCount);
} catch (error) {
fail("DYNAMIC_INVENTORY_INVALID", error instanceof Error ? error.message : String(error));
}
}
if (index && plan) {
try {
assert.equal(index.schemaVersion, 1);
assert.equal(index.operation, "BLENDER_WEB_CAPABILITY_TASK_INDEX");
assert.equal(sha(index.source.path), index.source.sha256);
assert.equal(sha(index.catalog.path), index.catalog.sha256);
const terminal = index.activeTask === null && plan.tasks?.every?.((task) => task.ready !== true && task.status === "done");
if (!terminal) assert.equal(index.activeTask, currentTask);
assert.equal(plan.operation, "FUNCTION_MODULE_MIGRATION_PLAN");
assert.ok(["ACTIVE_MODULE_EXECUTION_QUEUE", "COMPLETED_MODULE_EXECUTION"].includes(plan.status));
} catch (error) {
fail("PLAN_OR_INDEX_INVALID", error instanceof Error ? error.message : String(error));
}
}
if (parent && currentTask) {
if (parent.status !== "done") fail("PARENT_NOT_DONE", `${parentPath} status=${parent.status}`);
if (parent.nextTask !== currentTask) fail("PARENT_NEXT_TASK_MISMATCH", `${parent.nextTask ?? "NONE"}!=${currentTask}`);
}
const tasks = plan?.tasks ?? [];
// The task list is the authoritative execution record. Keep compatibility with
// older plans that also have a top-level module summary, but count every module
// task so later appended function slices cannot disappear from the audit.
const modules = tasks.filter((task) => task.module).map((task) => ({ id: task.module.moduleId }));
const active = tasks.filter((task) => task.ready === true && task.status === "in_progress");
const currentEntry = tasks.find((task) => task.id === currentTask);
const terminal = currentEntry?.status === "done" && currentEntry.ready === false && currentEntry.id === tasks.at(-1)?.id && index?.activeTask === null;
if (terminal) {
if (active.length !== 0) fail("TERMINAL_ACTIVE_MODULES", `count=${active.length}`);
} else {
if (active.length !== 1) fail("ACTIVE_MODULE_COUNT", `count=${active.length}`);
if (active[0]?.id !== currentTask) fail("ACTIVE_MODULE_POINTER_MISMATCH", `${active[0]?.id ?? "NONE"}!=${currentTask}`);
}
if (new Set(tasks.map((task) => task.id)).size !== tasks.length) fail("DUPLICATE_TASK_ID", "module plan has duplicate task IDs");
if (new Set(modules.map((module) => module.id)).size !== modules.length) fail("DUPLICATE_MODULE_ID", "module plan has duplicate module IDs");
const inventory = plan?.inventory;
if (!inventory || !exists(inventory.path)) fail("INVENTORY_MISSING", inventory?.path ?? "missing inventory declaration");
else {
try {
if (sha(inventory.path) !== inventory.sha256) fail("INVENTORY_HASH_DRIFT", inventory.path);
const sourceInventory = json(inventory.path);
if (sourceInventory.summary.inventoryEntries !== 6900 || inventory.total !== 6900) fail("INVENTORY_TOTAL_DRIFT", "expected immutable total 6900");
if (inventory.effectiveCompleted !== 290 || inventory.effectivePending !== 6609) fail("INVENTORY_EFFECTIVE_DRIFT", "expected effective 290/6609 baseline");
} catch (error) {
fail("INVENTORY_INVALID", error instanceof Error ? error.message : String(error));
}
}
const forbiddenReceiptPattern = /WBV2-P(?:\d+)-(?:000|001|002|003)\/.*continuation|capability-continuation/u;
for (const task of tasks.filter((candidate) => candidate.module)) {
const module = task.module;
for (const source of module.sourcePaths ?? []) if (!exists(source)) fail("MODULE_SOURCE_MISSING", `${task.id}:${source}`);
if (module.fullFamilyParity !== false) fail("FULL_FAMILY_CLAIM", task.id);
if (task.status === "in_progress" || task.ready) {
if (!module.sourceBacked) fail("ACTIVE_MODULE_NOT_SOURCE_BACKED", task.id);
if ((module.positive ?? []).length === 0 || (module.negative ?? []).length === 0 || (module.recovery ?? []).length === 0) fail("MODULE_CASE_MATRIX_INCOMPLETE", task.id);
if ((module.commands ?? []).length === 0) fail("MODULE_VERIFICATION_COMMANDS_MISSING", task.id);
}
for (const receipt of module.reuseReceipts ?? []) {
if (forbiddenReceiptPattern.test(receipt.manifest) || forbiddenReceiptPattern.test(receipt.report)) fail("GENERIC_CONTINUATION_RECEIPT", `${task.id}:${receipt.manifest}`);
if (!exists(receipt.manifest) || !exists(receipt.report)) fail("REUSED_RECEIPT_MISSING", `${task.id}:${receipt.manifest} / ${receipt.report}`);
else {
try {
const manifest = json(receipt.manifest);
const report = json(receipt.report);
if (manifest.status !== "done") fail("REUSED_MANIFEST_NOT_DONE", receipt.manifest);
if (report.status !== "PASS") fail("REUSED_REPORT_NOT_PASS", receipt.report);
} catch (error) {
fail("REUSED_RECEIPT_INVALID", error instanceof Error ? error.message : String(error));
}
}
}
}
const bridge = tasks.find((task) => task.id === "WBV2-P1096-000");
if (!bridge || bridge.kind !== "bridge") fail("BRIDGE_MISSING", "generic continuation must be superseded by an explicit bridge");
const rootTask = tasks.find((task) => task.id === "WBV2-P1100-000");
if (!rootTask || rootTask.kind !== "enabling") fail("MODULE_ROOT_MISSING", "module root task is missing");
const productiveTaskIds = tasks.filter((task) => task.module && task.module.moduleId !== "INVENTORY_GATE").map((task) => task.id);
if (productiveTaskIds.length < 7) fail("MODULE_SCOPE_TOO_SMALL", `productive modules=${productiveTaskIds.length}`);
const report = {
schemaVersion: 1,
operation: "FUNCTION_MODULE_EXECUTION_VALIDATION",
status: issues.length === 0 ? "PASS" : "BLOCKED",
queue: { currentTask, parentManifest: parentPath, activeModule: active[0]?.module?.moduleId ?? null },
plan: { path: index?.source?.path ?? null, taskCount: tasks.length, moduleCount: modules.length },
inventory: plan?.inventory ?? null,
dynamicInventory: dynamicInventory ? {
path: dynamicInventoryPath,
sourceTreeSha256: dynamicInventory.authority.sourceTreeSha256,
sourceFiles: dynamicInventory.summary.sourceFiles,
unitCount: dynamicInventory.summary.unitCount,
planningEstimate: dynamicInventory.policy.planningEstimate,
hardTarget: dynamicInventory.policy.hardTarget,
verifiedUnits: dynamicInventory.coverage.verifiedUnits,
unverifiedUnits: dynamicInventory.coverage.unverifiedUnits,
} : null,
reuse: { bridgePresent: Boolean(bridge), productiveModules: productiveTaskIds.length, genericContinuationExcluded: issues.every(({ code }) => code !== "GENERIC_CONTINUATION_RECEIPT") },
verification: plan?.verificationPolicy ?? null,
issues,
};
process.stdout.write(`${JSON.stringify(report)}\n`);
if (issues.length > 0) process.exitCode = 2;