68 lines
12 KiB
JavaScript
68 lines
12 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 sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex");
|
|
const readJson = (file) => JSON.parse(fs.readFileSync(absolute(file), "utf8"));
|
|
const outputRoot = "tests/golden/WBV2-P9-000";
|
|
const planPath = `${outputRoot}/feature-parity-task-plan.json`;
|
|
const reportPath = `${outputRoot}/feature-parity-root-report.json`;
|
|
const statusPath = "docs/status/WBV2-P9-000.md";
|
|
const manifestPath = `${outputRoot}/manifest.json`;
|
|
const p8ManifestPath = "tests/golden/WBV2-P8-004/manifest.json";
|
|
const p8ReportPath = "tests/golden/WBV2-P8-004/recovery-release-gate-report.json";
|
|
const p8StatusPath = "docs/status/WBV2-P8-004.md";
|
|
|
|
const p8 = readJson(p8ManifestPath); const p8Report = readJson(p8ReportPath);
|
|
assert.equal(p8.task, "WBV2-P8-004"); assert.equal(p8.status, "blocked"); assert.ok(p8.nextTask === null || p8.nextTask === "WBV2-P9-000");
|
|
assert.equal(p8Report.decision.status, "READY_WITH_AUTHORIZED_REBASELINE"); assert.equal(p8Report.decision.fullHistoricalReproduction, false);
|
|
for (const artifact of Object.values(p8.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path);
|
|
|
|
const basePlan = readJson("tests/golden/WBV2-P8-004/recovery-task-plan.json");
|
|
assert.equal(basePlan.recoveryRoot, "WBV2-P8-000");
|
|
const tasks = basePlan.tasks.map((task) => ({ ...task, ready: false }));
|
|
const p9 = [
|
|
{ id: "WBV2-P9-000", phase: "P9", title: "authorize_feature_parity_continuation", kind: "enabling", owner: "PROGRAM", dependsOn: ["WBV2-P8-004"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p9-governance", gate: "G6", card: "docs/tasks/WBV2-P9-000.md", behavior: "Authorize feature parity continuation after provenance epoch 2 without claiming historical byte reproduction.", outputs: ["continuation receipt", "feature parity plan", "scope limits"], acceptance: ["P8 provenance evidence remains exact", "authorized baseline is explicit", "one feature task is active"], status: "done", ready: false, queueMutationAllowed: true },
|
|
{ id: "WBV2-P9-001", phase: "P9", title: "mesh_production_chromium_receipt", kind: "feature", owner: "MESH", dependsOn: ["WBV2-P9-000"], parityId: "CAP-MESH-POSITIVE-EDIT", implementationClass: "LOCAL_EXACT", parallelGroup: "p9-mesh", gate: "G6", card: "docs/tasks/WBV2-P9-001.md", behavior: "Bind the existing Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt.", outputs: ["Chromium mesh receipt", "negative matrix", "manifest"], acceptance: ["real meshTranslateVertex command passes", "desktop/WASM delta matches", "save/reopen is exact", "malformed/stale/unknown inputs fail closed"], status: "in_progress", ready: true, queueMutationAllowed: false },
|
|
{ id: "WBV2-P9-002", phase: "P9", title: "modifier_production_chromium_receipt", kind: "feature", owner: "MODIFIER", dependsOn: ["WBV2-P9-001"], parityId: "CAP-MODIFIER-STATE-MUTATION", implementationClass: "LOCAL_EXACT", parallelGroup: "p9-modifier", gate: "G6", card: "docs/tasks/WBV2-P9-002.md", behavior: "Bind the existing Modifier Main transaction to a production Chromium receipt.", outputs: ["Chromium modifier receipt", "negative matrix", "manifest"], acceptance: ["real modifierSetEnabled command passes", "desktop/WASM delta matches", "save/reopen is exact"], status: "planned", ready: false, queueMutationAllowed: false },
|
|
{ id: "WBV2-P9-003", phase: "P9", title: "asset_catalog_production_chromium_receipt", kind: "feature", owner: "ASSET", dependsOn: ["WBV2-P9-002"], parityId: "CAP-ASSET-CATALOG-MUTATION", implementationClass: "LOCAL_EXACT", parallelGroup: "p9-asset", gate: "G6", card: "docs/tasks/WBV2-P9-003.md", behavior: "Bind the existing Asset Catalog Main transaction and resource resolver to a production Chromium receipt.", outputs: ["Chromium asset receipt", "negative matrix", "manifest"], acceptance: ["real assetCatalogAppend command passes", "resource hash is bound", "save/reopen is exact"], status: "planned", ready: false, queueMutationAllowed: false },
|
|
{ id: "WBV2-P9-004", phase: "P9", title: "recompute_feature_parity_gate", kind: "enabling", owner: "RELEASE", dependsOn: ["WBV2-P9-003"], parityId: null, implementationClass: "LOCAL_BOUNDED", parallelGroup: "p9-release", gate: "G7", card: "docs/tasks/WBV2-P9-004.md", behavior: "Recompute declared feature parity claims from production Chromium receipts and authorized provenance.", outputs: ["feature parity gate", "limited release declaration", "manifest"], acceptance: ["only evidenced feature claims are emitted", "authorized baseline remains explicit", "full historical reproduction remains false"], status: "planned", ready: false, queueMutationAllowed: false },
|
|
];
|
|
const plan = { ...basePlan, planId: "BLENDER_WEB_PARITY_V2_FEATURE_EPOCH_1", recoveryRoot: "WBV2-P9-000", parentRecoveryPlan: { path: "tests/golden/WBV2-P8-004/recovery-task-plan.json", sha256: sha256("tests/golden/WBV2-P8-004/recovery-task-plan.json") }, tasks: [...tasks, ...p9] };
|
|
|
|
fs.mkdirSync(absolute(outputRoot), { recursive: true }); fs.writeFileSync(absolute(planPath), `${JSON.stringify(plan, null, 2)}\n`);
|
|
const report = { schemaVersion: 1, task: "WBV2-P9-000", operation: "AUTHORIZE_FEATURE_PARITY_CONTINUATION", status: "PASS", parent: { task: p8.task, manifest: p8ManifestPath, manifestSha256: sha256(p8ManifestPath), previousDecision: p8Report.decision.status, fullHistoricalReproduction: p8Report.decision.fullHistoricalReproduction }, continuation: { root: "WBV2-P9-000", firstTask: "WBV2-P9-001", plannedTasks: 5, scope: ["MESH", "MODIFIER", "ASSET_CATALOG"], browser: "chromium" }, policy: { historicalEvidencePreserved: true, authorizedRebaselineAccepted: true, featureParityClaimsRemainEvidenceBound: true, fullHistoricalReproduction: false }, nextTask: "WBV2-P9-001" };
|
|
fs.writeFileSync(absolute(reportPath), `${JSON.stringify(report, null, 2)}\n`);
|
|
const rootCard = `# WBV2-P9-000: feature parity continuation root\n\n- task: WBV2-P9-000\n- parent: WBV2-P8-004\n- status: done\n- gap: workflow:authorize_feature_parity_continuation\n- ownerFamily: PROGRAM\n- targetImplementationClass: LOCAL_BOUNDED\n\n## 目标\n\nAuthorize the next feature-parity evidence epoch after provenance epoch 2. The release scope remains authorized rebaseline only.\n\n## 验收\n\nnode tools/web/generate-wbv2-feature-parity-root.mjs\nnode tools/web/check-execution-control-plane.mjs\nnode tools/web/check-v2-task-index.mjs\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P9-000/\`\n- Manifest: \`tests/golden/WBV2-P9-000/manifest.json\`\n- Rollback: restore P8-004 as queue parent without changing provenance evidence.\n`;
|
|
fs.writeFileSync(absolute("docs/tasks/WBV2-P9-000.md"), rootCard);
|
|
const activeCard = `# WBV2-P9-001: Mesh production Chromium receipt\n\n- task: WBV2-P9-001\n- parent: WBV2-P9-000\n- status: in_progress\n- gap: workflow:mesh_production_chromium_receipt\n- ownerFamily: MESH\n- targetImplementationClass: LOCAL_EXACT\n\n## 目标\n\nBind the real Mesh Main transaction to a production Chromium desktop/WASM/save-reopen receipt using the existing source implementation.\n\n## 输入与范围\n\n- Existing Mesh protocol: \`web/protocol/corrective-mesh-command.ts\`\n- Existing exact pilot: \`tests/golden/corrective/C4-002/receipt-report.json\`\n- Chromium test: \`web/tests/e2e/wbv2-mesh-production.spec.ts\`\n\n## 验收\n\n- \`npm --prefix web run test:e2e -- --workers=1 tests/e2e/wbv2-mesh-production.spec.ts\`\n- \`node tools/web/generate-wbv2-mesh-receipt.mjs --write\`\n- \`node tools/web/check-task-context.mjs --task WBV2-P9-001 --write\`\n\nMalformed, stale-revision, unknown-vertex, non-Chromium, or non-exact save/reopen cases must keep in_progress and must not advance nextTask.\n\n## 交付与回滚\n\n- Reports: \`tests/golden/WBV2-P9-001/\`\n- Status: \`docs/status/WBV2-P9-001.md\`\n- Manifest: \`tests/golden/WBV2-P9-001/manifest.json\`\n- Rollback: restore P9-000 as queue parent without modifying P8 evidence.\n`;
|
|
fs.writeFileSync(absolute("docs/tasks/WBV2-P9-001.md"), activeCard);
|
|
const rootStatus = `# WBV2-P9-000 status\n\n- task: \`WBV2-P9-000\`; parent: \`WBV2-P8-004\`; status: \`done\`\n- nextTask: \`WBV2-P9-001\`\n\nFeature parity continuation is authorized after provenance epoch 2. Work is limited to evidenced Mesh, Modifier, and Asset Catalog behavior in Chromium; full historical reproduction remains false.\n`;
|
|
fs.mkdirSync(absolute("docs/status"), { recursive: true }); fs.writeFileSync(absolute("docs/status/WBV2-P9-000.md"), rootStatus);
|
|
|
|
// Authorize the continuation on the prior gate without changing its evidence
|
|
// classification or historical provenance claims.
|
|
p8.nextTask = "WBV2-P9-000"; p8.continuation = { authorized: true, root: "WBV2-P9-000", scope: "FEATURE_PARITY_ONLY" };
|
|
p8Report.nextTask = "WBV2-P9-000"; p8Report.decision.nextTask = "WBV2-P9-000"; p8Report.negative.queueAdvance = "AUTHORIZED_CONTINUATION";
|
|
const currentP8Status = fs.readFileSync(absolute(p8StatusPath), "utf8").trim();
|
|
const p8Status = currentP8Status.includes("authorized continuation: `WBV2-P9-000`")
|
|
? `${currentP8Status}\n`
|
|
: `${currentP8Status}\n- authorized continuation: \`WBV2-P9-000\`\n\nFeature parity work may continue under a new manifest root. This does not change the authorized-rebaseline-only release scope or historical reproduction limitation.\n`;
|
|
fs.writeFileSync(absolute(p8ReportPath), `${JSON.stringify(p8Report, null, 2)}\n`); fs.writeFileSync(absolute(p8StatusPath), p8Status);
|
|
fs.writeFileSync(absolute(p8ManifestPath), `${JSON.stringify(p8, null, 2)}\n`);
|
|
execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P8-004", "--write"], { cwd: root, stdio: "pipe" });
|
|
const p8Artifacts = Object.fromEntries(Object.entries(p8.artifacts).map(([name, artifact]) => [name, { ...artifact, sha256: sha256(artifact.path) }])); p8.artifacts = p8Artifacts; fs.writeFileSync(absolute(p8ManifestPath), `${JSON.stringify(p8, null, 2)}\n`);
|
|
|
|
const rootArtifactPaths = { parentManifest: p8ManifestPath, parentReport: p8ReportPath, approval: "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json", plan: planPath, report: reportPath, rootCard: "docs/tasks/WBV2-P9-000.md", rootStatus: "docs/status/WBV2-P9-000.md", activeCard: "docs/tasks/WBV2-P9-001.md" };
|
|
const artifacts = Object.fromEntries(Object.entries(rootArtifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
|
const manifest = { schemaVersion: 1, task: "WBV2-P9-000", parentTask: "WBV2-P8-004", operation: "AUTHORIZE_FEATURE_PARITY_CONTINUATION", status: "done", enablingTask: true, parityStateChange: false, artifacts, assertions: { authorizedRebaseline: true, fullHistoricalReproduction: false, featureParityScope: ["MESH", "MODIFIER", "ASSET_CATALOG"] }, nextTask: "WBV2-P9-001" };
|
|
fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", planPath], { cwd: root, stdio: "inherit" });
|
|
let queue = fs.readFileSync(absolute("docs/EXECUTION_QUEUE.md"), "utf8"); queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P9-001` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P9-000/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P9-001.md`](tasks/WBV2-P9-001.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue);
|
|
process.stdout.write(`wbv2-feature-parity-root-ok root=WBV2-P9-000 next=WBV2-P9-001 scope=MESH,MODIFIER,ASSET_CATALOG\n`);
|