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 read = (relativePath) => fs.readFileSync(path.join(root, relativePath), "utf8"); const ledgerBytes = fs.readFileSync(path.join(root, "docs/status/parity-ledger.json")); const ledger = JSON.parse(ledgerBytes); const report = JSON.parse(read("docs/status/release-evidence.json")); const overview = read("docs/PROJECT_STATUS_AND_NEXT_WORK.md"); const parity = read("docs/BLENDER_5_2_WEB_FEATURE_PARITY.md"); const n015 = read("docs/status/N-015.md"); const n026 = read("docs/status/N-026.md"); const vdbPlan = read("docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md"); const expectedFamilies = Array.from({ length: 12 }, (_, index) => `N-${String(index + 15).padStart(3, "0")}`); assert.deepEqual(ledger.families.map((family) => family.id), expectedFamilies, "parity ledger family order or coverage drifted"); assert.deepEqual(report.families, ledger.families, "release evidence family snapshot is stale"); assert.equal( report.sourceSha256, crypto.createHash("sha256").update(ledgerBytes).digest("hex"), "release evidence source hash is stale", ); const blockedParityFamilies = ledger.families.filter((family) => family.parityStatus === "BLOCKED").map((family) => family.id); const blockedReleaseFamilies = ledger.families.filter((family) => family.releaseStatus === "BLOCKED").map((family) => family.id); const falseEvidence = []; for (const [group, values] of Object.entries(report.evidence)) { if (group === "records") continue; for (const [key, value] of Object.entries(values)) if (value === false) falseEvidence.push(`${group}.${key}`); } const missingCount = blockedReleaseFamilies.length + falseEvidence.length; assert.equal(blockedParityFamilies.length, 12, "this baseline expects N-015 through N-026 parity to remain explicitly blocked"); assert.deepEqual(blockedReleaseFamilies, [], "all declared V1 family slices should be ready"); assert.deepEqual(falseEvidence.sort(), []); assert.equal(missingCount, 0); for (const document of [overview, parity]) { assert.match(document, /17 条(?:成功 )?(?:command\/output\/artifact-hash )?(?:有效)?记录|17 条有效记录/); assert.match(document, /0 个 V1 缺失/); assert.match(document, /parityStatus/); } for (const document of [overview, n015, n026, vdbPlan]) { assert.match(document, /desktop\/server converter|desktop\/server OpenVDB|desktop\/server converter|server job/); assert.match(document, /双生产视口|主线程\/Offscreen 生产视口|主线程\/OffscreenCanvas/); assert.match(document, /demand paging|demand-page/); assert.match(document, /发布 golden|desktop\/Chromium.*golden/); } process.stdout.write( `status-consistency-ok families=${ledger.families.length} parityBlocked=${blockedParityFamilies.length} releaseBlocked=${blockedReleaseFamilies.length} evidenceRecords=${report.evidence.records.length} missing=${missingCount}\n`, );