165 lines
8.6 KiB
JavaScript
165 lines
8.6 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 write = process.argv.includes("--write");
|
|
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 outputRoot = "tests/golden/WBV2-P9-004";
|
|
const reportPath = `${outputRoot}/feature-parity-gate-report.json`;
|
|
const statusPath = "docs/status/WBV2-P9-004.md";
|
|
const planPath = `${outputRoot}/feature-parity-task-plan.json`;
|
|
const manifestPath = `${outputRoot}/manifest.json`;
|
|
const parentManifestPath = "tests/golden/WBV2-P9-003/manifest.json";
|
|
const approvalPath = "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json";
|
|
|
|
const parent = readJson(parentManifestPath);
|
|
assert.equal(parent.task, "WBV2-P9-003");
|
|
assert.equal(parent.status, "done");
|
|
assert.equal(parent.nextTask, "WBV2-P9-004");
|
|
for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path);
|
|
|
|
const approval = readJson(approvalPath);
|
|
assert.equal(approval.decision, "APPROVED");
|
|
assert.equal(approval.epoch, 2);
|
|
assert.equal(approval.approvedBy, "wangdequan");
|
|
assert.equal(approval.limitations.fullHistoricalReproduction, false);
|
|
assert.equal(approval.limitations.replacementIsHistoricalRestoration, false);
|
|
assert.equal(approval.limitations.releaseLabel, "AUTHORIZED_REBASELINE_ONLY");
|
|
|
|
const receipts = [
|
|
{ family: "MESH", capabilityId: "CAP-MESH-POSITIVE-EDIT", manifest: "tests/golden/WBV2-P9-001/manifest.json", report: "tests/golden/WBV2-P9-001/mesh-receipt-report.json" },
|
|
{ family: "MODIFIER", capabilityId: "CAP-MODIFIER-STATE-MUTATION", manifest: "tests/golden/WBV2-P9-002/manifest.json", report: "tests/golden/WBV2-P9-002/modifier-receipt-report.json" },
|
|
{ family: "ASSET_CATALOG", capabilityId: "CAP-ASSET-CATALOG-MUTATION", manifest: "tests/golden/WBV2-P9-003/manifest.json", report: "tests/golden/WBV2-P9-003/asset-catalog-receipt-report.json" },
|
|
];
|
|
const checked = receipts.map((entry) => {
|
|
const manifest = readJson(entry.manifest);
|
|
const report = readJson(entry.report);
|
|
assert.equal(manifest.status, "done", `${entry.family} manifest is not done`);
|
|
assert.equal(manifest.nextTask, entry.family === "ASSET_CATALOG" ? "WBV2-P9-004" : entry.family === "MODIFIER" ? "WBV2-P9-003" : "WBV2-P9-002");
|
|
assert.equal(report.status, "PASS", `${entry.family} receipt is not PASS`);
|
|
assert.equal(report.browser, "chromium", `${entry.family} receipt is not Chromium evidence`);
|
|
assert.equal(report.queueMutation, false, `${entry.family} receipt mutated the queue`);
|
|
assert.equal(report.assertions.historicalReproduction, false, `${entry.family} receipt claims historical reproduction`);
|
|
assert.equal(report.assertions.saveReopenExact, true, `${entry.family} receipt lacks exact save/reopen`);
|
|
assert.equal(report.chromium.deterministic, true, `${entry.family} receipt is not deterministic`);
|
|
const bound = Object.values(manifest.artifacts ?? {}).find((artifact) => artifact.path === entry.report);
|
|
assert.ok(bound, `${entry.family} report is not manifest-bound`);
|
|
assert.equal(bound.sha256, sha256(entry.report), `${entry.family} report hash drift`);
|
|
return {
|
|
family: entry.family,
|
|
capabilityId: entry.capabilityId,
|
|
manifest: entry.manifest,
|
|
manifestSha256: sha256(entry.manifest),
|
|
report: entry.report,
|
|
reportSha256: sha256(entry.report),
|
|
browser: report.browser,
|
|
surfaces: report.chromium.surfaces,
|
|
deterministic: report.chromium.deterministic,
|
|
saveReopen: report.assertions.saveReopenExact ? "EXACT" : "UNPROVEN",
|
|
negativeMatrixClosed: report.assertions.failureMatrixClosed === true,
|
|
};
|
|
});
|
|
|
|
const gate = {
|
|
schemaVersion: 1,
|
|
task: "WBV2-P9-004",
|
|
operation: "RECOMPUTE_FEATURE_PARITY_GATE",
|
|
status: "PASS",
|
|
decision: {
|
|
status: "READY_WITH_BOUNDED_FEATURE_PARITY",
|
|
code: "FEATURE_PARITY_AUTHORIZED_REBASELINE",
|
|
featureParityClaims: checked.map((entry) => entry.capabilityId),
|
|
featureParityClaimCount: checked.length,
|
|
provenanceEpoch: approval.epoch,
|
|
releaseScope: approval.limitations.releaseLabel,
|
|
fullHistoricalReproduction: approval.limitations.fullHistoricalReproduction,
|
|
historicalOriginalsRestored: false,
|
|
},
|
|
receipts: checked,
|
|
negative: {
|
|
missingReceipt: "REJECTED",
|
|
receiptHashDrift: "REJECTED",
|
|
unsupportedBrowser: "REJECTED",
|
|
nonExactSaveReopen: "REJECTED",
|
|
falseHistoricalReproduction: "REJECTED",
|
|
undeclaredFeatureClaim: "REJECTED",
|
|
},
|
|
policy: {
|
|
authorizedRebaselineOnly: true,
|
|
sourceHistoryReadOnly: true,
|
|
claimsAreEvidenceBound: true,
|
|
terminalQueuePointer: true,
|
|
},
|
|
nextTask: null,
|
|
};
|
|
|
|
if (!write) {
|
|
process.stdout.write(`wbv2-feature-parity-gate-ok task=WBV2-P9-004 claims=${checked.length} epoch=${approval.epoch} release=${approval.limitations.releaseLabel}\n`);
|
|
process.exit(0);
|
|
}
|
|
|
|
fs.mkdirSync(absolute(outputRoot), { recursive: true });
|
|
fs.writeFileSync(absolute(reportPath), `${JSON.stringify(gate, null, 2)}\n`);
|
|
const status = `# WBV2-P9-004 status\n\n- task: \`WBV2-P9-004\`; parent: \`WBV2-P9-003\`; status: \`done\`\n- evidenced feature claims: \`3\`\n- claims: \`CAP-MESH-POSITIVE-EDIT\`, \`CAP-MODIFIER-STATE-MUTATION\`, \`CAP-ASSET-CATALOG-MUTATION\`\n- provenance: epoch \`2\`, \`AUTHORIZED_REBASELINE_ONLY\`\n- fullHistoricalReproduction: \`false\`\n- nextTask: \`NONE\`\n\nThe gate emits only claims backed by deterministic Chromium production receipts with exact save/reopen evidence. The project owner-approved epoch 2 baseline remains explicitly separate from unavailable historical bytes; this is not a full historical reproduction claim. P9-004 remains the terminal execution pointer because no successor is authorized.\n`;
|
|
fs.writeFileSync(absolute(statusPath), status);
|
|
|
|
const previousPlan = readJson("tests/golden/WBV2-P9-003/feature-parity-task-plan.json");
|
|
const nextPlan = structuredClone(previousPlan);
|
|
nextPlan.status = "COMPLETED_WITH_BOUNDED_FEATURE_PARITY";
|
|
nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P9-003/feature-parity-task-plan.json", sha256: sha256("tests/golden/WBV2-P9-003/feature-parity-task-plan.json") };
|
|
// Keep one active terminal pointer for the execution index; the manifest below
|
|
// is the completion record and deliberately has no successor.
|
|
nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P9-004"
|
|
? { ...task, status: "in_progress", ready: true }
|
|
: { ...task, ready: false });
|
|
fs.writeFileSync(absolute(planPath), `${JSON.stringify(nextPlan, null, 2)}\n`);
|
|
execFileSync(process.execPath, [absolute("tools/web/generate-v2-task-index.mjs"), "--plan-path", absolute(planPath)], { cwd: root, stdio: "inherit" });
|
|
execFileSync(process.execPath, [absolute("tools/web/check-task-context.mjs"), "--task", "WBV2-P9-004", "--write"], { cwd: root, stdio: "inherit" });
|
|
|
|
const artifactPaths = {
|
|
parentManifest: parentManifestPath,
|
|
approval: approvalPath,
|
|
meshManifest: receipts[0].manifest,
|
|
meshReport: receipts[0].report,
|
|
modifierManifest: receipts[1].manifest,
|
|
modifierReport: receipts[1].report,
|
|
assetManifest: receipts[2].manifest,
|
|
assetReport: receipts[2].report,
|
|
generator: "tools/web/generate-wbv2-feature-parity-gate.mjs",
|
|
report: reportPath,
|
|
status: statusPath,
|
|
featureParityPlan: planPath,
|
|
taskContext: `${outputRoot}/task-context.json`,
|
|
};
|
|
const artifacts = Object.fromEntries(Object.entries(artifactPaths).map(([name, file]) => [name, { path: file, sha256: sha256(file) }]));
|
|
const manifest = {
|
|
schemaVersion: 1,
|
|
task: "WBV2-P9-004",
|
|
parentTask: "WBV2-P9-003",
|
|
operation: "RECOMPUTE_FEATURE_PARITY_GATE",
|
|
status: "done",
|
|
enablingTask: true,
|
|
parityStateChange: true,
|
|
runtime: "PLAYWRIGHT_CHROMIUM_DESKTOP_AND_WASM",
|
|
artifacts,
|
|
assertions: {
|
|
featureParityClaims: checked.map((entry) => entry.capabilityId),
|
|
featureParityClaimCount: checked.length,
|
|
deterministicReceipts: checked.length,
|
|
exactSaveReopen: checked.length,
|
|
provenanceEpoch: approval.epoch,
|
|
authorizedRebaselineOnly: true,
|
|
fullHistoricalReproduction: false,
|
|
},
|
|
nextTask: null,
|
|
};
|
|
fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
process.stdout.write(`wbv2-feature-parity-gate-written task=WBV2-P9-004 claims=${checked.length} epoch=${approval.epoch} release=${approval.limitations.releaseLabel} terminal=true artifacts=${Object.keys(artifacts).length}\n`);
|