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>
154 lines
8.5 KiB
JavaScript
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;
|