94 lines
13 KiB
JavaScript
94 lines
13 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 absolute = (file) => path.join(root, file);
|
|
const read = (file) => fs.readFileSync(absolute(file), "utf8");
|
|
const readJson = (file) => JSON.parse(read(file));
|
|
const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex");
|
|
const p13ManifestPath = "tests/golden/WBV2-P13-005/manifest.json";
|
|
const p13ReportPath = "tests/golden/WBV2-P13-005/high-value-domain-gate-report.json";
|
|
const p13StatusPath = "docs/status/WBV2-P13-005.md";
|
|
const p13ContextPath = "tests/golden/WBV2-P13-005/task-context.json";
|
|
const p14Root = "tests/golden/WBV2-P14-000";
|
|
const planPath = `${p14Root}/coverage-task-plan.json`;
|
|
const reportPath = `${p14Root}/coverage-root-report.json`;
|
|
const manifestPath = `${p14Root}/manifest.json`;
|
|
const statusPath = "docs/status/WBV2-P14-000.md";
|
|
const parityMapPath = "tests/golden/WBV2-P0-002/parity-map.json";
|
|
const matrixPath = "docs/BLENDER_WASM_CAPABILITY_MATRIX_TEMPLATE.json";
|
|
|
|
const p13 = readJson(p13ManifestPath);
|
|
const p13Report = readJson(p13ReportPath);
|
|
assert.equal(p13.task, "WBV2-P13-005");
|
|
assert.equal(p13.status, "done");
|
|
assert.equal(p13.nextTask, null);
|
|
assert.equal(p13Report.status, "PASS");
|
|
assert.equal(p13Report.decision.fullHistoricalReproduction, false);
|
|
assert.equal(p13Report.decision.inventoryPending, 6618);
|
|
for (const artifact of Object.values(p13.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path);
|
|
const parityMap = readJson(parityMapPath);
|
|
assert.equal(parityMap.summary.inventoryEntries, 6900);
|
|
assert.equal(parityMap.summary.pendingLegacyEntries, 6618);
|
|
assert.equal(parityMap.summary.capabilityCount, 15);
|
|
|
|
const tasks = [
|
|
{ id: "WBV2-P14-000", phase: "P14", title: "authorize_inventory_coverage_continuation", kind: "enabling", owner: "PROGRAM", dependsOn: ["WBV2-P13-005"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p14-governance", gate: "G0", card: "docs/tasks/WBV2-P14-000.md", behavior: "Authorize a machine-readable 6900-entry coverage continuation without reopening completed production receipts.", outputs: ["coverage root", "batch plan", "scope limits"], acceptance: ["P13 evidence remains hash-bound", "inventory counts are deterministic", "one coverage task is active"], status: "done", ready: false, queueMutationAllowed: true },
|
|
{ id: "WBV2-P14-001", phase: "P14", title: "generate_inventory_coverage_ledger", kind: "enabling", owner: "PARITY", dependsOn: ["WBV2-P14-000"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p14-ledger", gate: "G0", card: "docs/tasks/WBV2-P14-001.md", behavior: "Cluster all 6900 inventory entries by capability and bind representative evidence without repeated Blender or Chromium execution.", outputs: ["coverage ledger", "capability counts", "batch digest"], acceptance: ["all entries are accounted for", "pending remainder stays explicit", "existing receipts are reused", "no duplicate execution"], status: "in_progress", ready: true, queueMutationAllowed: false },
|
|
{ id: "WBV2-P14-002", phase: "P14", title: "reconcile_capability_evidence_matrix", kind: "enabling", owner: "PARITY", dependsOn: ["WBV2-P14-001"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p14-matrix", gate: "G2", card: "docs/tasks/WBV2-P14-002.md", behavior: "Reconcile capability-level evidence classes and representative slices from the coverage ledger.", outputs: ["evidence matrix", "claim map", "unproven map"], acceptance: ["only hash-bound claims are promoted", "partial capability coverage is explicit", "6900 remainder is unchanged"], status: "planned", ready: false, queueMutationAllowed: false },
|
|
{ id: "WBV2-P14-003", phase: "P14", title: "close_inventory_coverage_gate", kind: "enabling", owner: "RELEASE", dependsOn: ["WBV2-P14-002"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p14-release", gate: "G5", card: "docs/tasks/WBV2-P14-003.md", behavior: "Close the coverage gate with a limited declaration and machine-checkable batching policy.", outputs: ["coverage gate", "efficiency declaration", "next batch policy"], acceptance: ["all entries have a capability bucket", "feature claims remain evidence-bound", "no historical or inventory over-claim"], status: "planned", ready: false, queueMutationAllowed: false },
|
|
];
|
|
const plan = { schemaVersion: 1, planId: "BLENDER_WEB_PARITY_V2_INVENTORY_COVERAGE_EPOCH_1", status: "ACTIVE_INVENTORY_COVERAGE_QUEUE", authority: "queue_reactivated_after_p13_high_value_gate", productContract: "docs/WEB_BLENDER_MODELER_V1_SCOPE.md", 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: "existing_receipts_before_new_runs" }, coveragePolicy: { inventoryTotal: 6900, pendingAtStart: 6618, grouping: "capability-family", duplicateValidation: "forbidden", historicalBytes: "read-only" }, tasks };
|
|
fs.mkdirSync(absolute(p14Root), { recursive: true });
|
|
fs.writeFileSync(absolute(planPath), `${JSON.stringify(plan, null, 2)}\n`);
|
|
const report = { schemaVersion: 1, task: "WBV2-P14-000", operation: "AUTHORIZE_INVENTORY_COVERAGE_CONTINUATION", status: "PASS", parent: { task: p13.task, manifest: p13ManifestPath, manifestSha256: sha256(p13ManifestPath), report: p13ReportPath, reportSha256: sha256(p13ReportPath), previousDecision: p13Report.decision.status, fullHistoricalReproduction: false }, continuation: { root: "WBV2-P14-000", firstTask: "WBV2-P14-001", plannedTasks: 4, inventoryTotal: 6900, inventoryPending: 6618, capabilityBuckets: parityMap.summary.capabilityCount, grouping: "capability-family", browser: "chromium", noRepeatedExecution: true }, policy: { p13EvidencePreserved: true, sourceHistoryReadOnly: true, authorizedRebaselineOnly: true, duplicateValidationAvoided: true, inventoryRemainderExplicit: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P14-001" };
|
|
fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`);
|
|
fs.writeFileSync(absolute("docs/tasks/WBV2-P14-000.md"), `# WBV2-P14-000: inventory coverage continuation root\n\n- task: WBV2-P14-000\n- parent: WBV2-P13-005\n- status: done\n- gap: workflow:authorize_inventory_coverage_continuation\n- ownerFamily: PROGRAM\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nAuthorize a machine-readable continuation for the 6900-entry inventory. P14 first groups entries by capability family and reuses hash-bound evidence; it does not reopen completed Blender or Chromium receipts.\n\n## 验收\n\n- \`node tools/web/generate-wbv2-coverage-root.mjs\`\n- \`node tools/web/check-execution-control-plane.mjs\`\n- \`node tools/web/check-v2-task-index.mjs\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P14-000/\`\n- Manifest: \`tests/golden/WBV2-P14-000/manifest.json\`\n- Rollback: restore P13-005 as queue parent without changing P13 evidence.\n`);
|
|
fs.writeFileSync(absolute(statusPath), `# WBV2-P14-000 status\n\n- task: \`WBV2-P14-000\`; parent: \`WBV2-P13-005\`; status: \`done\`\n- inventory scope: \`6900\` total, \`6618\` pending\n- capability buckets: \`${parityMap.summary.capabilityCount}\`; duplicate validation: \`forbidden\`\n- nextTask: \`WBV2-P14-001\`\n\nP14 is an authorized coverage continuation. It preserves the P13 high-value declaration and starts with a capability-family ledger so one representative receipt can be reused without claiming the entire family is complete.\n`);
|
|
|
|
p13Report.nextTask = "WBV2-P14-000";
|
|
p13Report.policy = { ...(p13Report.policy ?? {}), terminalQueuePointer: false, authorizedContinuation: "WBV2-P14-000" };
|
|
fs.writeFileSync(absolute(p13ReportPath), `${JSON.stringify(p13Report, null, 2)}\n`);
|
|
const p13Status = read(p13StatusPath).trim();
|
|
fs.writeFileSync(absolute(p13StatusPath), p13Status.includes("authorized continuation") ? `${p13Status}\n` : `${p13Status}\n- authorized continuation: \`WBV2-P14-000\`\n\nInventory coverage may continue under a new root without changing the high-value claim boundary.\n`);
|
|
p13.nextTask = "WBV2-P14-000";
|
|
p13.continuation = { authorized: true, root: "WBV2-P14-000", scope: "INVENTORY_COVERAGE_BATCHING" };
|
|
fs.writeFileSync(absolute(p13ManifestPath), `${JSON.stringify(p13, null, 2)}\n`);
|
|
execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P13-005", "--write"], { cwd: root, stdio: "pipe" });
|
|
p13.artifacts = Object.fromEntries(Object.entries(p13.artifacts).map(([name, artifact]) => [name, { ...artifact, sha256: sha256(artifact.path) }]));
|
|
fs.writeFileSync(absolute(p13ManifestPath), `${JSON.stringify(p13, null, 2)}\n`);
|
|
|
|
for (const task of tasks) {
|
|
const card = task.id === "WBV2-P14-000"
|
|
? read("docs/tasks/WBV2-P14-000.md")
|
|
: (() => {
|
|
const entrypoints = { "WBV2-P14-001": "generate-wbv2-coverage-ledger.mjs", "WBV2-P14-002": "generate-wbv2-capability-evidence-matrix.mjs", "WBV2-P14-003": "generate-wbv2-inventory-coverage-gate.mjs" };
|
|
const generator = entrypoints[task.id];
|
|
return `# ${task.id}: ${task.title}\n\n- task: ${task.id}\n- parent: ${task.dependsOn[0]}\n- status: ${task.status}\n- gap: workflow:${task.title}\n- ownerFamily: ${task.owner}\n- targetImplementationClass: ${task.implementationClass}\n\n## 目标\n\n${task.behavior}\n\n## 输入与范围\n\n- Focused input: \`tests/golden/WBV2-P14-000/coverage-root-report.json\`\n- Full inventory source (streamed by generator): \`tests/golden/WBV2-P0-002/parity-map.json\`\n- Parent evidence: \`tests/golden/${task.dependsOn[0]}/manifest.json\`\n- Production entrypoint: \`node tools/web/${generator} --write\`\n\n## 验收\n\n- all 6900 entries remain accounted for\n- hash-bound evidence is reused before any new execution\n- malformed, hash-drift, unsupported, or false-completion input keeps in_progress\n- \`node tools/web/${generator} --write\`\n- \`node tools/web/check-task-context.mjs --task ${task.id} --write\`\n\n## 交付与回滚\n\n- Reports: \`tests/golden/${task.id}/\`\n- Status: \`docs/status/${task.id}.md\`\n- Manifest: \`tests/golden/${task.id}/manifest.json\`\n- Rollback: restore ${task.dependsOn[0]} as queue parent.\n`;
|
|
})();
|
|
fs.writeFileSync(absolute(`docs/tasks/${task.id}.md`), card);
|
|
}
|
|
const rootArtifactPaths = { parentManifest: p13ManifestPath, parentReport: p13ReportPath, approval: "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", parityMap: parityMapPath, capabilityMatrix: matrixPath, plan: planPath, report: reportPath, rootCard: "docs/tasks/WBV2-P14-000.md", rootStatus: statusPath };
|
|
const artifacts = Object.fromEntries(Object.entries(rootArtifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
|
const manifest = { schemaVersion: 1, task: "WBV2-P14-000", parentTask: "WBV2-P13-005", operation: "AUTHORIZE_INVENTORY_COVERAGE_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, runtime: "READ_ONLY_INVENTORY_COVERAGE_ROOT", artifacts, assertions: { p13EvidencePreserved: true, inventoryTotal: 6900, inventoryPending: 6618, capabilityBuckets: parityMap.summary.capabilityCount, duplicateValidationAvoided: true, authorizedRebaselineOnly: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P14-001" };
|
|
fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" });
|
|
let queue = read("docs/EXECUTION_QUEUE.md");
|
|
queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P14-001` |")
|
|
.replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P14-000/manifest.json` |")
|
|
.replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P14-001.md`](tasks/WBV2-P14-001.md) |");
|
|
fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue);
|
|
let nextTaskFile = read("nextTask.md");
|
|
nextTaskFile = nextTaskFile.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P14-001` |")
|
|
.replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `in_progress` |")
|
|
.replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P14-000/manifest.json` |")
|
|
.replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P14-001.md` |")
|
|
.replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `WBV2-P14-002` |")
|
|
.replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-coverage-ledger.mjs --write` |");
|
|
fs.writeFileSync(absolute("nextTask.md"), nextTaskFile);
|
|
process.stdout.write("wbv2-coverage-root-written root=WBV2-P14-000 next=WBV2-P14-001 inventory=6900 pending=6618 buckets=15\n");
|