Files
workinf_Blender_Wasm/tools/web/audit-wbv2-feature-completeness.mjs
mes123456 f87a72732c
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
test(web): enforce complete one-pass smoke closure
2026-09-07 11:47:42 +08:00

85 lines
5.8 KiB
JavaScript

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 readJson = (relative) => JSON.parse(fs.readFileSync(path.join(root, relative), "utf8"));
const sha = (relative) => crypto.createHash("sha256").update(fs.readFileSync(path.join(root, relative))).digest("hex");
const report = readJson("tests/golden/WBV2-P1424-001/product-implementation-report.json");
const catalog = readJson("web/app/src/capabilities/blender-feature-route-catalog.json");
const smokePlan = readJson("tests/golden/WBV2/feature-smoke-plan.json");
const smokeReport = readJson("tests/golden/WBV2/feature-smoke-report.json");
const smokeFix = readJson("tests/golden/WBV2/feature-smoke-fix-report.json");
const wasmManifest = readJson("web/app/public/wasm-module-manifest.json");
const countBy = (items, selector) => Object.fromEntries([...new Set(items.map(selector))].sort().map((key) => [key, items.filter((item) => selector(item) === key).length]));
const unverified = catalog.entries.filter((entry) => entry.evidenceStatus === "UNVERIFIED");
const failedSmoke = smokeReport.cases.filter((entry) => entry.status !== "PASS");
const focusedPasses = new Set(smokeFix.fixes.filter((entry) => entry.status === "PASS").map((entry) => entry.featureId));
const unresolvedSmoke = failedSmoke.filter((entry) => !focusedPasses.has(entry.featureId));
const implementationResults = report.implementationTasks.map((task) => ({
id: task.id,
module: task.module,
status: task.status,
resultPath: task.resultPath ?? null,
resultPresent: task.resultPath ? fs.existsSync(path.join(root, task.resultPath)) : false,
}));
const missingResults = implementationResults.filter((entry) => !entry.resultPresent);
const audit = {
schemaVersion: 1,
auditId: "WBV2-FEATURE-COMPLETENESS-001",
operation: "DETAILED_MIGRATION_COMPLETENESS_AUDIT",
status: missingResults.length || unresolvedSmoke.length ? "PARTIAL_BLOCKED" : "IMPLEMENTATION_COMPLETE",
implementation: {
workflowModules: { total: report.workflowModules.length, implemented: report.workflowModules.filter((item) => item.status === "implemented").length },
productTasks: { total: report.implementationTasks.length, implemented: report.implementationTasks.filter((item) => item.status === "implemented").length, missingResultFiles: missingResults },
},
routeCoverage: {
unitCount: catalog.unitCount,
classifiedCount: catalog.classifiedCount,
unclassifiedCount: catalog.unclassifiedCount,
counts: catalog.counts,
unavailable: catalog.entries.filter((entry) => entry.route === "UNAVAILABLE").map((entry) => entry.id),
byKind: countBy(catalog.entries, (entry) => entry.kind),
byFamily: countBy(catalog.entries, (entry) => entry.family),
},
behavioralEvidence: {
status: catalog.behavioralEvidence.status,
verifiedUnits: catalog.behavioralEvidence.verifiedUnits,
unverifiedUnits: catalog.behavioralEvidence.unverifiedUnits,
unverifiedByKind: countBy(unverified, (entry) => entry.kind),
unverifiedByFamily: countBy(unverified, (entry) => entry.family),
rule: "route assignment is not behavioral completion",
},
smoke: {
planId: smokePlan.planId,
totalFeatures: smokePlan.cases.length,
attempts: smokeReport.cases.reduce((sum, entry) => sum + Number(entry.attempts ?? 0), 0),
passed: smokeReport.cases.filter((entry) => entry.status === "PASS").length,
resolved: smokeReport.cases.filter((entry) => entry.status === "PASS").length + focusedPasses.size,
initialFailed: failedSmoke,
unresolved: unresolvedSmoke,
focusedFix: smokeFix.fixes,
retries: smokeFix.retries,
},
wasmLifecycle: wasmManifest.modules.map((module) => ({ id: module.id, lifecycle: module.lifecycle, preload: module.preload, single: module.resources?.single?.fileName ?? null, pthread: module.resources?.pthread?.fileName ?? null })),
actualMissingOrBlocked: [
{ id: "IO_IMPORT_WASM_ARTIFACT", status: "RESOLVED", description: "importScene/exportScene is compiled into the source-matched WebEngine WASM and passed native ABI plus focused Chromium checks.", evidence: "tests/golden/WBV2/feature-smoke-fix-report.json" },
{ id: "BEHAVIORAL_EVIDENCE_OVERLAY", status: "DEFERRED", description: "2720 classified source units still lack exact behavioral receipts; they remain routed, not claimed verified.", evidence: "web/app/src/capabilities/blender-feature-route-catalog.json" },
],
nextWork: {
priority: ["schedule batched evidence for unverified operators/RNA/macros/modifier units"],
forbidden: ["do not rerun passed feature smoke cases", "do not mark route assignment as behavioral verification", "do not replace WASM with a simulated JS implementation"],
},
inputs: {
productReportSha256: sha("tests/golden/WBV2-P1424-001/product-implementation-report.json"),
routeCatalogSha256: sha("web/app/src/capabilities/blender-feature-route-catalog.json"),
smokeReportSha256: sha("tests/golden/WBV2/feature-smoke-report.json"),
},
};
const outputPath = path.join(root, "tests/golden/WBV2/feature-completeness-audit.json");
fs.writeFileSync(outputPath, `${JSON.stringify(audit, null, 2)}\n`);
process.stdout.write(`wbv2-feature-completeness-audit status=${audit.status} modules=${audit.implementation.workflowModules.implemented}/${audit.implementation.workflowModules.total} tasks=${audit.implementation.productTasks.implemented}/${audit.implementation.productTasks.total} routes=${audit.routeCoverage.classifiedCount}/${audit.routeCoverage.unitCount} verified=${audit.behavioralEvidence.verifiedUnits} unverified=${audit.behavioralEvidence.unverifiedUnits} smokeResolved=${audit.smoke.resolved}/${audit.smoke.totalFeatures} blocked=${audit.actualMissingOrBlocked.filter((item) => item.status === "BLOCKED").length}\n`);