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>
311 lines
24 KiB
JavaScript
311 lines
24 KiB
JavaScript
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 writeJson = (file, value) => {
|
|
fs.mkdirSync(path.dirname(abs(file)), { recursive: true });
|
|
fs.writeFileSync(abs(file), `${JSON.stringify(value, null, 2)}\n`);
|
|
};
|
|
const writeText = (file, value) => {
|
|
fs.mkdirSync(path.dirname(abs(file)), { recursive: true });
|
|
fs.writeFileSync(abs(file), value);
|
|
};
|
|
|
|
if (!process.argv.includes("--write")) {
|
|
console.log("usage: node tools/web/reorganize-wbv2-module-execution.mjs --write");
|
|
process.exit(1);
|
|
}
|
|
|
|
const queuePath = "docs/EXECUTION_QUEUE.md";
|
|
const inventoryPath = "tests/golden/WBV2-P0-002/parity-map.json";
|
|
const previousTask = "WBV2-P1096-000";
|
|
const previousParent = "tests/golden/WBV2-P1095-003/manifest.json";
|
|
const bridgeManifestPath = `tests/golden/${previousTask}/manifest.json`;
|
|
const rootTask = "WBV2-P1100-000";
|
|
const firstModuleTask = "WBV2-P1100-001";
|
|
const planPath = `tests/golden/${rootTask}/module-execution-plan.json`;
|
|
const rootReportPath = `tests/golden/${rootTask}/module-execution-root-report.json`;
|
|
const rootStatusPath = `docs/status/${rootTask}.md`;
|
|
const rootManifestPath = `tests/golden/${rootTask}/manifest.json`;
|
|
const inventory = json(inventoryPath);
|
|
const parent = json(previousParent);
|
|
assert.equal(parent.status, "done");
|
|
assert.equal(parent.nextTask, previousTask);
|
|
|
|
const bridgeReportPath = `tests/golden/${previousTask}/module-queue-bridge-report.json`;
|
|
const bridgeStatusPath = `docs/status/${previousTask}.md`;
|
|
writeJson(bridgeReportPath, {
|
|
schemaVersion: 1,
|
|
task: previousTask,
|
|
operation: "SUPERSEDE_GENERIC_CONTINUATION_QUEUE",
|
|
status: "PASS",
|
|
parent: { task: parent.task, manifest: previousParent, manifestSha256: sha(previousParent) },
|
|
decision: {
|
|
superseded: true,
|
|
parityStateChange: false,
|
|
noCapabilityClaim: true,
|
|
reason: "The generated continuation queue repeated existing markers without a module contract.",
|
|
replacementRoot: rootTask,
|
|
},
|
|
inventory: { total: inventory.summary.inventoryEntries, pending: inventory.summary.pendingLegacyEntries, effectiveCompleted: 290, effectivePending: 6609 },
|
|
nextTask: rootTask,
|
|
});
|
|
writeText(bridgeStatusPath, `# ${previousTask} status\n\n- task: \`${previousTask}\`; parent: \`${parent.task}\`; status: \`done\`\n- operation: \`SUPERSEDE_GENERIC_CONTINUATION_QUEUE\`\n- no Blender capability completion claimed; repeated continuation is replaced by module execution\n- inventory unchanged: \`6900\` total, effective \`290/6609\`\n- nextTask: \`${rootTask}\`\n`);
|
|
writeJson(bridgeManifestPath, {
|
|
schemaVersion: 1,
|
|
task: previousTask,
|
|
parentTask: parent.task,
|
|
operation: "SUPERSEDE_GENERIC_CONTINUATION_QUEUE",
|
|
status: "done",
|
|
enablingTask: true,
|
|
parityStateChange: false,
|
|
runtime: "MODULE_EXECUTION_QUEUE_BRIDGE",
|
|
artifacts: {
|
|
parentManifest: { path: previousParent, sha256: sha(previousParent) },
|
|
report: { path: bridgeReportPath, sha256: sha(bridgeReportPath) },
|
|
status: { path: bridgeStatusPath, sha256: sha(bridgeStatusPath) },
|
|
},
|
|
assertions: {
|
|
supersededGenericContinuation: true,
|
|
noCapabilityClaim: true,
|
|
inventoryTotal: 6900,
|
|
effectiveCompleted: 290,
|
|
effectivePending: 6609,
|
|
historicalReproduction: false,
|
|
},
|
|
nextTask: rootTask,
|
|
});
|
|
|
|
const source = {
|
|
core: [
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp",
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_main_state.h",
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_api.cpp",
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp",
|
|
"web/protocol/web-engine.ts",
|
|
"web/app/src/workers/web-engine.worker.ts",
|
|
],
|
|
render: [
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp",
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_main_state.h",
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_api.cpp",
|
|
"blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp",
|
|
"web/protocol/scene-ir.ts",
|
|
"web/protocol/web-engine.ts",
|
|
"web/app/src/workers/web-engine.worker.ts",
|
|
"web/app/src/app/App.tsx",
|
|
"web/app/src/vendor/blender/web_engine.wasm",
|
|
],
|
|
};
|
|
|
|
const receipts = (tasks) => tasks.map((task) => ({
|
|
manifest: `tests/golden/${task}/manifest.json`,
|
|
report: `tests/golden/${task}/implementation-report.json`,
|
|
}));
|
|
const moduleTask = ({ id, moduleId, owner, parentId, status, ready, title, capabilities, sourcePaths, reuseReceipts, positive, negative, recovery, commands, sourceBacked = true }) => ({
|
|
id,
|
|
phase: id.match(/^WBV2-P(\d+)/u)?.[1] ?? "1100",
|
|
title,
|
|
kind: "module",
|
|
owner,
|
|
dependsOn: [parentId],
|
|
parityId: moduleId,
|
|
implementationClass: "LOCAL_EXACT",
|
|
parallelGroup: `module-${moduleId.toLowerCase()}`,
|
|
gate: "MODULE",
|
|
card: `docs/tasks/${id}.md`,
|
|
behavior: `Complete the ${moduleId} module through its shared Blender Main primitives and aggregate case matrix.`,
|
|
outputs: ["module receipt", "negative matrix", "manifest", "status"],
|
|
acceptance: ["source and protocol hashes are bound", "positive Main mutation is proven", "negative and recovery cases are proven", "Chromium and save/reopen receipts are exact", "full-family parity remains explicit"],
|
|
status,
|
|
ready,
|
|
queueMutationAllowed: true,
|
|
module: { moduleId, sourceBacked, capabilities, sourcePaths, reuseReceipts, positive, negative, recovery, commands, fullFamilyParity: false },
|
|
});
|
|
|
|
const moduleTasks = [
|
|
moduleTask({
|
|
id: firstModuleTask,
|
|
moduleId: "RENDER_LIGHT_CAMERA",
|
|
owner: "RENDER",
|
|
parentId: rootTask,
|
|
status: "in_progress",
|
|
ready: true,
|
|
title: "verify_render_light_camera_module",
|
|
capabilities: ["CAP-RENDER-LIGHT-TYPE", "CAP-RENDER-LIGHT-AREA-SHAPE", "CAP-RENDER-LIGHT-CONTRIBUTION-FACTORS", "CAP-RENDER-LIGHT-SHADOW-CONTROLS", "CAP-RENDER-LIGHT-CASCADE-CONTROLS", "CAP-RENDER-LIGHT-AREA-SIZE-Z", "CAP-RENDER-LIGHT-CLIP-START", "CAP-RENDER-WORLD-LIGHTING-CONTROLS", "CAP-RENDER-WORLD-PROBE-CONTROLS", "CAP-RENDER-WORLD-ENVIRONMENT-STRENGTH", "CAP-RENDER-CAMERA-DOF-FOCUS-OBJECT", "CAP-RENDER-CAMERA-PANORAMA"],
|
|
sourcePaths: source.render,
|
|
reuseReceipts: receipts(["WBV2-P595-002", "WBV2-P596-002", "WBV2-P597-002", "WBV2-P598-002", "WBV2-P599-002", "WBV2-P600-002", "WBV2-P601-002", "WBV2-P602-002", "WBV2-P603-002", "WBV2-P604-002", "WBV2-P605-002", "WBV2-P606-002"]),
|
|
positive: ["setLightProperties", "setWorldProperties", "setCameraProperties", "camera panorama", "world environment", "light shadow/cascade"],
|
|
negative: ["invalid enum", "invalid numeric bounds", "near/far conflict", "unknown target", "stale revision"],
|
|
recovery: ["undo", "redo", "save/reopen", "worker disposal"],
|
|
commands: [
|
|
"npm --prefix web run typecheck",
|
|
"npm --prefix web run test:lighting-field-roundtrip",
|
|
"npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-lighting-fields-production.spec.ts tests/e2e/lighting-field-roundtrip.spec.ts",
|
|
],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1100-002", moduleId: "SCENE_OBJECT_MESH", owner: "SCENE_MESH", parentId: firstModuleTask, status: "planned", ready: false, title: "verify_scene_object_mesh_module",
|
|
capabilities: ["CAP-MESH-TOPOLOGY-FAMILY", "CAP-CORE-SCENE-OBJECT", "CAP-OBJECT-MOVE-COLLECTION"], sourcePaths: source.core,
|
|
reuseReceipts: [{ manifest: "tests/golden/WBV2-P11-001/manifest.json", report: "tests/golden/WBV2-P11-001/mesh-topology-receipt-report.json" }, { manifest: "tests/golden/WBV2-P12-002/manifest.json", report: "tests/golden/WBV2-P12-002/scene-object-receipt-report.json" }, { manifest: "tests/golden/WBV2-P24-002/manifest.json", report: "tests/golden/WBV2-P24-002/object-move-receipt-report.json" }],
|
|
positive: ["mesh topology", "visibility", "transform", "collection membership"], negative: ["invalid selection", "stale revision", "linked data"], recovery: ["undo", "redo", "save/reopen"], commands: ["npm --prefix web run typecheck", "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-topology-production.spec.ts tests/e2e/wbv2-scene-object-production.spec.ts"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1100-003", moduleId: "MATERIAL_ANIMATION", owner: "MATERIAL_ANIMATION", parentId: "WBV2-P1100-002", status: "planned", ready: false, title: "verify_material_animation_module",
|
|
capabilities: ["CAP-MATERIAL-ANIMATION"], sourcePaths: source.core, reuseReceipts: [{ manifest: "tests/golden/WBV2-P12-003/manifest.json", report: "tests/golden/WBV2-P12-003/material-animation-receipt-report.json" }],
|
|
positive: ["principled material", "image node", "keyframe", "FCurve"], negative: ["unsupported graph", "stale revision"], recovery: ["undo", "redo", "save/reopen"], commands: ["npm --prefix web run typecheck", "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-material-animation-production.spec.ts"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1101-000", moduleId: "NONMESH_GEOMETRY", owner: "GEOMETRY", parentId: "WBV2-P1100-003", status: "planned", ready: false, title: "verify_nonmesh_geometry_module",
|
|
capabilities: ["CAP-VIEWPORT-NONMESH", "CAP-NATIVE-DATABLOCK"], sourcePaths: source.core, reuseReceipts: [{ manifest: "tests/golden/WBV2-P12-004/manifest.json", report: "tests/golden/WBV2-P12-004/viewport-nonmesh-receipt-report.json" }, { manifest: "tests/golden/WBV2-P29-003/manifest.json", report: "tests/golden/WBV2-P29-003/implementation-report.json" }],
|
|
positive: ["curve", "surface", "font", "volume", "metaball", "grease pencil"], negative: ["unsupported data", "resource missing", "malformed geometry"], recovery: ["save/reopen", "resource disposal"], commands: ["npm --prefix web run typecheck", "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-viewport-nonmesh-production.spec.ts"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1101-001", moduleId: "NODES_SIMULATION", owner: "NODES_SIMULATION", parentId: "WBV2-P1101-000", status: "planned", ready: false, title: "verify_nodes_simulation_module",
|
|
capabilities: ["CAP-GEOMETRY-NODES", "CAP-SIMULATION"], sourcePaths: source.core, reuseReceipts: [{ manifest: "tests/golden/WBV2-P13-002/manifest.json", report: "tests/golden/WBV2-P13-002/geometry-nodes-receipt-report.json" }, { manifest: "tests/golden/WBV2-P13-004/manifest.json", report: "tests/golden/WBV2-P13-004/advanced-domain-receipt-report.json" }],
|
|
positive: ["allowlisted node graph", "physics manifest", "stable hash"], negative: ["unsupported node", "budget exceeded", "stale revision"], recovery: ["save/reopen", "cache disposal"], commands: ["npm --prefix web run test:geometry-node-main-reader", "npm --prefix web run test:physics-main-reader"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1101-002", moduleId: "ASSET_IO", owner: "ASSET", parentId: "WBV2-P1101-001", status: "planned", ready: false, title: "verify_asset_io_module",
|
|
capabilities: ["CAP-ASSET-LINK-OVERRIDE-RELOAD", "CAP-ASSET-CATALOG-MUTATION"], sourcePaths: source.core, reuseReceipts: [{ manifest: "tests/golden/WBV2-P11-003/manifest.json", report: "tests/golden/WBV2-P11-003/asset-link-override-receipt-report.json" }, { manifest: "tests/golden/WBV2-P10-003/manifest.json", report: "tests/golden/WBV2-P10-003/module-matrix-receipt-report.json" }],
|
|
positive: ["append", "link", "override", "reload", "asset catalog v2"], negative: ["missing source", "ownership violation", "hash drift", "collision"], recovery: ["undo", "redo", "save/reopen", "IndexedDB restart"], commands: ["npm --prefix web run test:asset-catalog-m12-evidence", "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-asset-link-override-production.spec.ts tests/e2e/wbv2-asset-catalog-production.spec.ts"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1101-003", moduleId: "SCULPT_PAINT", owner: "SCULPT_PAINT", parentId: "WBV2-P1101-002", status: "planned", ready: false, title: "verify_sculpt_paint_module",
|
|
capabilities: ["CAP-PAINT-ATTRIBUTES", "CAP-SCULPT-PAINT"], sourcePaths: source.core, reuseReceipts: [{ manifest: "tests/golden/WBV2-P16-002/manifest.json", report: "tests/golden/WBV2-P16-002/paint-attributes-receipt-report.json" }],
|
|
positive: ["vertex colors", "vertex weights", "bounded sculpt stroke"], negative: ["mirror unverified", "invalid patch", "unsupported brush"], recovery: ["undo", "redo", "save/reopen"], commands: ["npm --prefix web run test:paint-roundtrip", "npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-paint-attributes-production.spec.ts"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1102-000", moduleId: "UI_EDITOR", owner: "EDITOR", parentId: "WBV2-P1101-003", status: "planned", ready: false, title: "implement_ui_editor_module",
|
|
capabilities: ["CAP-UI-EDITOR"], sourcePaths: ["web/protocol/editor-workflow.ts", "web/app/src/app/App.tsx", "web/app/src/workers/web-engine.worker.ts"], reuseReceipts: [], sourceBacked: false,
|
|
positive: ["editor context", "workspace", "area/region"], negative: ["unsupported editor", "invalid context"], recovery: ["worker restart", "save/reopen"], commands: ["npm --prefix web run test:editor-main-reader", "npm --prefix web run typecheck"],
|
|
}),
|
|
moduleTask({
|
|
id: "WBV2-P1102-001", moduleId: "INVENTORY_GATE", owner: "RELEASE", parentId: "WBV2-P1102-000", status: "planned", ready: false, title: "close_module_execution_gate",
|
|
capabilities: [], sourcePaths: [inventoryPath, "tests/golden/WBV2-P1100-000/module-execution-plan.json"], reuseReceipts: [],
|
|
positive: ["aggregate module receipts", "catalog hash"], negative: ["missing receipt", "hash drift", "false completion"], recovery: ["re-run affected module only"], commands: ["node tools/web/check-wbv2-module-execution.mjs", "npm --prefix web run build"],
|
|
}),
|
|
];
|
|
|
|
const bridgeTask = {
|
|
id: previousTask,
|
|
phase: "1096",
|
|
title: "supersede_generic_continuation_queue",
|
|
kind: "bridge",
|
|
owner: "PROGRAM",
|
|
dependsOn: [parent.task],
|
|
parityId: null,
|
|
implementationClass: "QUEUE_ONLY",
|
|
parallelGroup: "bridge",
|
|
gate: "QUEUE",
|
|
card: `docs/tasks/${previousTask}.md`,
|
|
behavior: "Replace the generic continuation queue with a finite module execution plan without claiming capability parity.",
|
|
outputs: ["bridge manifest", "status"],
|
|
acceptance: ["no parity claim", "inventory preserved", "module plan hash-bound"],
|
|
status: "done",
|
|
ready: false,
|
|
queueMutationAllowed: true,
|
|
};
|
|
const rootRecord = {
|
|
id: rootTask,
|
|
phase: "1100",
|
|
title: "reorganize_module_execution_plan",
|
|
kind: "enabling",
|
|
owner: "PROGRAM",
|
|
dependsOn: [previousTask],
|
|
parityId: null,
|
|
implementationClass: "QUEUE_ONLY",
|
|
parallelGroup: "module-root",
|
|
gate: "MODULE",
|
|
card: `docs/tasks/${rootTask}.md`,
|
|
behavior: "Reuse completed source-backed work and activate finite module-level implementation and verification.",
|
|
outputs: ["module plan", "manifest", "status"],
|
|
acceptance: ["completed receipts reused", "generic continuation excluded", "one module active", "inventory preserved"],
|
|
status: "done",
|
|
ready: false,
|
|
queueMutationAllowed: true,
|
|
};
|
|
const tasks = [bridgeTask, rootRecord, ...moduleTasks];
|
|
const plan = {
|
|
schemaVersion: 1,
|
|
planId: "BLENDER_WEB_MODULE_EXECUTION_EPOCH_3",
|
|
operation: "FUNCTION_MODULE_MIGRATION_PLAN",
|
|
status: "ACTIVE_MODULE_EXECUTION_QUEUE",
|
|
authority: "blender_main_source_and_existing_hash_bound_receipts",
|
|
executionPointer: queuePath,
|
|
inventory: { path: inventoryPath, sha256: sha(inventoryPath), total: 6900, legacyCompleted: 281, legacyPending: 6618, effectiveCompleted: 290, effectivePending: 6609, mutation: "forbidden_by_module_execution" },
|
|
reusePolicy: { completedReceipts: "reuse_without_rerun", continuationEvidence: "excluded", duplicateValidation: "forbidden", fullFamilyParity: "never_inferred" },
|
|
verificationPolicy: { browser: "chromium_only", required: ["sourceHash", "wasmBuild", "positiveMainMutation", "negativeNoMutation", "undoRedo", "saveReopen", "aggregateManifest"], failure: "keep_module_in_progress_and_do_not_advance" },
|
|
modules: moduleTasks.map((task) => ({ id: task.module.moduleId, task: task.id, owner: task.owner, sourceBacked: task.module.sourceBacked, capabilities: task.module.capabilities, reusedReceipts: task.module.reuseReceipts, fullFamilyParity: false })),
|
|
tasks,
|
|
};
|
|
writeJson(planPath, plan);
|
|
|
|
writeText(`docs/tasks/${rootTask}.md`, `# ${rootTask}: reorganize_module_execution_plan\n\n- task: ${rootTask}\n- parent: ${previousTask}\n- status: done\n- gap: workflow:function_module_migration_plan\n- ownerFamily: PROGRAM\n- targetImplementationClass: QUEUE_ONLY\n\n## 目标\n\nReuse completed source-backed Blender work and switch execution to finite function/module workflows.\n\n## 输入与范围\n\n- Existing receipts: \`tests/golden/WBV2-P10-002/\`, \`tests/golden/WBV2-P11-004/\`, \`tests/golden/WBV2-P12-005/\`, \`tests/golden/WBV2-P13-005/\`, \`tests/golden/WBV2-P595-002/\` through \`tests/golden/WBV2-P606-002/\`\n- Module plan: \`${planPath}\`\n- Validator: \`node tools/web/check-wbv2-module-execution.mjs\`\n\n## 验收\n\n- completed receipts are reused and hash-checked\n- generic continuation evidence is excluded from productive module claims\n- one module task is active\n- inventory remains 6900 / effective 290/6609\n\n## 交付与回滚\n\n- Manifest: \`${rootManifestPath}\`\n- Rollback: restore ${previousTask} as queue parent without rewriting prior receipts.\n`);
|
|
for (const task of moduleTasks) {
|
|
const module = task.module;
|
|
const receiptLines = module.reuseReceipts.length === 0 ? "- None; source-backed implementation must be established before activation" : module.reuseReceipts.map((item) => `- \`${item.manifest}\`\n- \`${item.report}\``).join("\n");
|
|
writeText(`docs/tasks/${task.id}.md`, `# ${task.id}: ${task.title}\n\n- task: ${task.id}\n- parent: ${task.dependsOn[0]}\n- status: ${task.status}\n- gap: workflow:module_${module.moduleId.toLowerCase()}\n- ownerFamily: ${task.owner}\n- targetImplementationClass: LOCAL_EXACT\n- moduleId: ${module.moduleId}\n\n## 目标\n\nComplete one coherent Blender function module through shared Main primitives and an aggregate operator case matrix.\n\n## 输入与范围\n\n- Source paths:\n${module.sourcePaths.map((item) => `- \`${item}\``).join("\n")}\n- Reused receipts:\n${receiptLines}\n- Implementation and verification entrypoint: \`node tools/web/run-wbv2-module-task.mjs --task ${task.id} --write\`\n\n## 验证\n\nPositive cases: ${module.positive.join(", ")}\nNegative boundaries: ${module.negative.join(", ")}\nRecovery: ${module.recovery.join(", ")}\nCommands:\n${module.commands.map((item) => `- \`${item}\``).join("\n")}\n\nA module advances only when source hashes, positive Main mutation, negative no-mutation, undo/redo, save/reopen, Chromium and aggregate manifest checks pass. A representative case never claims full-family parity.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${task.id}/\`\n- Manifest: \`tests/golden/${task.id}/manifest.json\`\n- Status: \`docs/status/${task.id}.md\`\n- Rollback: restore ${task.dependsOn[0]} as queue parent and leave this module in_progress.\n`);
|
|
writeText(`docs/status/${task.id}.md`, `# ${task.id} status\n\n- task: \`${task.id}\`; parent: \`${task.dependsOn[0]}\`; status: \`${task.status}\`\n- module: \`${module.moduleId}\`; sourceBacked: \`${module.sourceBacked}\`; fullFamilyParity: \`false\`\n- positive/negative/recovery verification is required before handoff\n- inventory remains: \`6900\` total, effective \`290/6609\`\n- nextTask: \`${tasks[tasks.findIndex((candidate) => candidate.id === task.id) + 1]?.id ?? "NONE"}\`\n`);
|
|
}
|
|
writeJson(rootReportPath, {
|
|
schemaVersion: 1,
|
|
task: rootTask,
|
|
operation: "REORGANIZE_FUNCTION_MODULE_EXECUTION",
|
|
status: "PASS",
|
|
parent: { task: previousTask, manifest: bridgeManifestPath, manifestSha256: sha(bridgeManifestPath) },
|
|
reused: { completedModuleReceipts: ["WBV2-P10-002", "WBV2-P10-003", "WBV2-P11-001", "WBV2-P11-002", "WBV2-P11-003", "WBV2-P11-004", "WBV2-P12-002", "WBV2-P12-003", "WBV2-P12-004", "WBV2-P13-002", "WBV2-P13-003", "WBV2-P13-004", "WBV2-P15-002", "WBV2-P16-002", "WBV2-P24-002", "WBV2-P595-002..WBV2-P606-002"], noRerun: true },
|
|
modules: moduleTasks.length,
|
|
activeModule: firstModuleTask,
|
|
verification: plan.verificationPolicy,
|
|
inventory: plan.inventory,
|
|
nextTask: firstModuleTask,
|
|
});
|
|
writeText(rootStatusPath, `# ${rootTask} status\n\n- task: \`${rootTask}\`; parent: \`${previousTask}\`; status: \`done\`\n- execution model: \`FUNCTION_MODULE_MIGRATION\`\n- completed source/WASM/Chromium receipts reused without rerun\n- modules planned: \`${moduleTasks.length}\`; active module: \`${moduleTasks[0].module.moduleId}\`\n- verification requires source hash, Main mutation, negative no-mutation, undo/redo, save/reopen, Chromium and aggregate manifest\n- inventory unchanged: \`6900\` total, effective \`290/6609\`\n- nextTask: \`${firstModuleTask}\`\n`);
|
|
writeJson(rootManifestPath, {
|
|
schemaVersion: 1,
|
|
task: rootTask,
|
|
parentTask: previousTask,
|
|
operation: "REORGANIZE_FUNCTION_MODULE_EXECUTION",
|
|
status: "done",
|
|
enablingTask: true,
|
|
parityStateChange: false,
|
|
runtime: "FUNCTION_MODULE_MIGRATION_QUEUE",
|
|
artifacts: {
|
|
parentManifest: { path: bridgeManifestPath, sha256: sha(bridgeManifestPath) },
|
|
plan: { path: planPath, sha256: sha(planPath) },
|
|
report: { path: rootReportPath, sha256: sha(rootReportPath) },
|
|
status: { path: rootStatusPath, sha256: sha(rootStatusPath) },
|
|
},
|
|
assertions: { moduleCount: moduleTasks.length, completedReceiptsReused: true, genericContinuationExcluded: true, inventoryTotal: 6900, effectiveCompleted: 290, effectivePending: 6609, verificationPolicyBound: true, fullFamilyParity: false, historicalReproduction: false },
|
|
nextTask: firstModuleTask,
|
|
});
|
|
|
|
execFileSync(process.execPath, [abs("tools/web/generate-v2-task-index.mjs"), "--plan-path", abs(planPath)], { cwd: root, stdio: "inherit" });
|
|
let queue = read(queuePath);
|
|
queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, `| 当前任务 | \`${firstModuleTask}\` |`)
|
|
.replace(/\| parent manifest \| `[^`]+` \|/u, `| parent manifest | \`${rootManifestPath}\` |`)
|
|
.replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, `| 任务卡 | [\`tasks/${firstModuleTask}.md\`](tasks/${firstModuleTask}.md) |`);
|
|
writeText(queuePath, queue);
|
|
execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", previousTask, "--write"], { cwd: root, stdio: "inherit" });
|
|
execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", rootTask, "--write"], { cwd: root, stdio: "inherit" });
|
|
execFileSync(process.execPath, [abs("tools/web/check-task-context.mjs"), "--task", firstModuleTask, "--write"], { cwd: root, stdio: "inherit" });
|
|
let next = read("nextTask.md");
|
|
const tick = String.fromCharCode(96);
|
|
next = next.replace(/\| Current task when this file was written \| `[^`]+` \|/u, `| Current task when this file was written | ${tick}${firstModuleTask}${tick} |`)
|
|
.replace(/\| Current task state \| `[^`]+` \|/u, `| Current task state | ${tick}in_progress${tick} |`)
|
|
.replace(/\| Parent manifest \| `[^`]+` \|/u, `| Parent manifest | ${tick}${rootManifestPath}${tick} |`)
|
|
.replace(/\| Current task card \| `[^`]+` \|/u, `| Current task card | ${tick}docs/tasks/${firstModuleTask}.md${tick} |`)
|
|
.replace(/\| Current task-context nextTask \| `[^`]+` \|/u, `| Current task-context nextTask | ${tick}WBV2-P1100-002${tick} |`)
|
|
.replace(/\| Focused command \| `[^`]+` \|/u, `| Focused command | ${tick}node tools/web/run-wbv2-module-task.mjs --task ${firstModuleTask} --write${tick} |`);
|
|
writeText("nextTask.md", next);
|
|
console.log(`module-execution-plan-written root=${rootTask} active=${firstModuleTask} modules=${moduleTasks.length} reusedReceipts=true inventory=6900 effectivePending=6609`);
|