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 json = (file) => JSON.parse(read(file)); const sha256 = (file) => crypto.createHash("sha256").update(fs.readFileSync(absolute(file))).digest("hex"); const outputRoot = "tests/golden/WBV2-P16-003"; const reportPath = `${outputRoot}/paint-gate-report.json`; const overlayPath = `${outputRoot}/inventory-completion-overlay.json`; const statusPath = "docs/status/WBV2-P16-003.md"; const planPath = `${outputRoot}/paint-task-plan.json`; const manifestPath = `${outputRoot}/manifest.json`; const parentPath = "tests/golden/WBV2-P16-002/manifest.json"; const receiptPath = "tests/golden/WBV2-P16-002/paint-attributes-receipt-report.json"; const selectionPath = "tests/golden/WBV2-P16-001/paint-selection-report.json"; const baseInventoryPath = "tests/golden/WBV2-P0-002/parity-map.json"; const coverageMatrixPath = "tests/golden/WBV2-P14-002/capability-evidence-matrix.json"; const p15GatePath = "tests/golden/WBV2-P15-003/lighting-gate-report.json"; const approvalPath = "docs/status/M12-PROVENANCE-EPOCH-2-APPROVAL.json"; const parent = json(parentPath); const receipt = json(receiptPath); const selection = json(selectionPath); const baseInventory = json(baseInventoryPath); const coverage = json(coverageMatrixPath); const p15 = json(p15GatePath); const approval = json(approvalPath); assert.equal(parent.task, "WBV2-P16-002"); assert.equal(parent.status, "done"); assert.equal(parent.nextTask, "WBV2-P16-003"); for (const artifact of Object.values(parent.artifacts ?? {})) assert.equal(sha256(artifact.path), artifact.sha256, artifact.path); assert.equal(receipt.status, "PASS"); assert.equal(receipt.assertions.inventoryBindingsExact, true); assert.equal(receipt.assertions.saveReopenExact, true); assert.equal(receipt.assertions.deterministic, true); assert.equal(selection.inventory.matchedEntries, 117); assert.equal(baseInventory.summary.inventoryEntries, 6900); assert.equal(baseInventory.summary.pendingLegacyEntries, 6618); assert.equal(coverage.inventory.pending, 6618); assert.equal(p15.status, "PASS"); assert.equal(approval.limitations.fullHistoricalReproduction, false); const bindings = receipt.inventoryBindings; assert.deepEqual(bindings.map((binding) => binding.id).sort(), ["operator:paint.vertex_color_set", "operator:paint.weight_set"]); assert(bindings.every((binding) => binding.exact === true)); const overlayEntries = bindings.map((binding) => ({ id: binding.id, capabilityId: "CAP-SCULPT-PAINT", sourceReceipt: receiptPath, sourceReceiptSha256: sha256(receiptPath), evidence: binding.evidence, exact: true, historicalRestoration: false })); const overlay = { schemaVersion: 1, task: "WBV2-P16-003", operation: "INVENTORY_COMPLETION_OVERLAY", status: "PASS", baseInventory: { path: baseInventoryPath, sha256: sha256(baseInventoryPath), total: 6900, pending: 6618 }, completionEvidence: { receipt: receiptPath, receiptSha256: sha256(receiptPath), deterministic: true, chromium: true, wasmMain: true, saveReopen: "EXACT" }, entries: overlayEntries, summary: { newlyVerifiedEntries: overlayEntries.length, effectiveCompleted: 281 + overlayEntries.length, effectivePending: 6618 - overlayEntries.length, claimedComplete: overlayEntries.length, basePendingPreserved: true, fullFamilyParity: false, historicalReproduction: false } }; const claims = [...p15.decision.featureParityClaims, "SCULPT.PAINT_ATTRIBUTES"]; const gate = { schemaVersion: 1, task: "WBV2-P16-003", operation: "CLOSE_PAINT_CAPABILITY_GATE", status: "PASS", decision: { status: "READY_WITH_PAINT_SLICE_AND_INVENTORY_OVERLAY", code: "PAINT_ATTRIBUTES_AUTHORIZED_REBASELINE", featureParityClaims: claims, featureParityClaimCount: claims.length, newFeatureClaim: "SCULPT.PAINT_ATTRIBUTES", newlyVerifiedInventoryEntries: overlayEntries.length, baseInventoryPending: 6618, effectivePending: 6616, effectiveCompleted: 283, claimedCompleteOverlay: 2, fullFamilyParity: false, engineBound: true, browser: "chromium", provenanceEpoch: approval.epoch, releaseScope: approval.limitations.releaseLabel, fullHistoricalReproduction: false }, evidence: { receipt: { path: receiptPath, sha256: sha256(receiptPath), bindings }, overlay: { path: overlayPath, sha256: "PENDING", entries: overlayEntries }, selection: { path: selectionPath, sha256: sha256(selectionPath), matchedEntries: selection.inventory.matchedEntries }, baseInventory: { path: baseInventoryPath, sha256: sha256(baseInventoryPath), pending: baseInventory.summary.pendingLegacyEntries }, coverageMatrix: { path: coverageMatrixPath, sha256: sha256(coverageMatrixPath) }, p15Gate: { path: p15GatePath, sha256: sha256(p15GatePath) }, approval: { path: approvalPath, sha256: sha256(approvalPath), epoch: approval.epoch } }, efficiency: { uniqueBehaviorRuns: 2, repeatedBlenderRuns: 0, repeatedChromiumRuns: 0, duplicateValidationAvoided: true, entriesVerifiedPerBehaviorBatch: overlayEntries.length, baseInventoryUntouched: true }, coverage: { baseTotal: 6900, baseCompleted: 281, basePending: 6618, overlayCompleted: 2, effectiveCompleted: 283, effectivePending: 6616, remainingPaintPending: 115 }, negative: { missingReceipt: "REJECTED", receiptHashDrift: "REJECTED", nonChromium: "REJECTED", nonExactSaveReopen: "REJECTED", malformedPaint: receipt.production.malformed.code, representativeAsFullFamily: "REJECTED", historicalRestorationClaim: "REJECTED" }, policy: { sourceHistoryReadOnly: true, authorizedRebaselineOnly: true, overlayOnlyCompletion: true, baseInventoryPreserved: true, inventoryRemainderExplicit: true, noFalseLocalParity: true, terminalQueuePointer: true }, nextTask: null }; if (!write) { process.stdout.write(`wbv2-paint-gate-ok task=WBV2-P16-003 claims=${claims.length} newlyVerified=2 basePending=6618 effectivePending=6616 remainingPaint=115 repeatedRuns=0 terminal=true\n`); process.exit(0); } fs.mkdirSync(absolute(outputRoot), { recursive: true }); fs.writeFileSync(absolute(overlayPath), `${JSON.stringify(overlay, null, 2)}\n`); gate.evidence.overlay.sha256 = sha256(overlayPath); fs.writeFileSync(absolute(reportPath), `${JSON.stringify(gate, null, 2)}\n`); fs.writeFileSync(absolute(statusPath), `# WBV2-P16-003 status\n\n- task: \`WBV2-P16-003\`; parent: \`WBV2-P16-002\`; status: \`done\`\n- new feature claim: \`SCULPT.PAINT_ATTRIBUTES\`; exact inventory bindings: \`2\`\n- graduated IDs: \`operator:paint.vertex_color_set\`, \`operator:paint.weight_set\`\n- base inventory: \`6900\` total, \`281\` completed, \`6618\` pending\n- effective overlay: \`283\` completed, \`6616\` pending, claimed complete overlay: \`2\`\n- repeated Blender/Chromium validation: \`0\`; unique behavior runs: \`2\`; duplicate validation avoided: \`true\`\n- provenance epoch: \`${approval.epoch}\`; release: \`AUTHORIZED_REBASELINE_ONLY\`; fullHistoricalReproduction: \`false\`\n- nextTask: \`NONE\`\n\nThe completion overlay graduates only two exact operator IDs whose color/weight protocol behavior was verified in deterministic Chromium/WASM Main receipts. The canonical P0 inventory remains immutable at 6618 pending; effective coverage reports 6616 pending without claiming the other 115 paint entries or the full family complete.\n`); const previousPlan = json("tests/golden/WBV2-P16-002/paint-task-plan.json"); const nextPlan = structuredClone(previousPlan); nextPlan.status = "COMPLETED_WITH_PAINT_SLICE_AND_OVERLAY"; nextPlan.parentRecoveryPlan = { path: "tests/golden/WBV2-P16-002/paint-task-plan.json", sha256: sha256("tests/golden/WBV2-P16-002/paint-task-plan.json") }; nextPlan.tasks = nextPlan.tasks.map((task) => task.id === "WBV2-P16-003" ? { ...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-P16-003", "--write"], { cwd: root, stdio: "inherit" }); const artifactPaths = { parentManifest: parentPath, receipt: receiptPath, selection: selectionPath, baseInventory: baseInventoryPath, coverageMatrix: coverageMatrixPath, p15Gate: p15GatePath, approval: approvalPath, overlay: overlayPath, report: reportPath, generator: "tools/web/generate-wbv2-paint-gate.mjs", status: statusPath, parityPlan: 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-P16-003", parentTask: "WBV2-P16-002", operation: "CLOSE_PAINT_CAPABILITY_GATE", status: "done", enablingTask: true, parityStateChange: true, runtime: "READ_ONLY_PAINT_GATE_WITH_COMPLETION_OVERLAY", artifacts, assertions: { totalFeatureClaims: claims.length, newPaintFeatureClaims: 1, exactInventoryBindings: 2, effectiveCompleted: 283, effectivePending: 6616, baseInventoryCompleted: 281, baseInventoryPending: 6618, claimedCompleteOverlay: 2, remainingPaintPending: 115, uniqueBehaviorRuns: 2, repeatedBlenderRuns: 0, repeatedChromiumRuns: 0, duplicateValidationAvoided: true, baseInventoryUntouched: true, provenanceEpoch: approval.epoch, authorizedRebaselineOnly: true, fullHistoricalReproduction: false, deterministic: true }, nextTask: null }; fs.writeFileSync(absolute(manifestPath), `${JSON.stringify(manifest, null, 2)}\n`); let queue = read("docs/EXECUTION_QUEUE.md"); queue = queue.replace(/\| 当前任务 \| `[^`]+` \|/u, "| 当前任务 | `WBV2-P16-003` |").replace(/\| parent manifest \| `[^`]+` \|/u, "| parent manifest | `tests/golden/WBV2-P16-002/manifest.json` |").replace(/\| 任务卡 \| \[[^\]]+\]\([^\)]+\) \|/u, "| 任务卡 | [`tasks/WBV2-P16-003.md`](tasks/WBV2-P16-003.md) |"); fs.writeFileSync(absolute("docs/EXECUTION_QUEUE.md"), queue); let nextTask = read("nextTask.md"); nextTask = nextTask.replace(/\| Current task when this file was written \| `[^`]+` \|/u, "| Current task when this file was written | `WBV2-P16-003` |").replace(/\| Current task state \| `[^`]+` \|/u, "| Current task state | `done` |").replace(/\| Parent manifest \| `[^`]+` \|/u, "| Parent manifest | `tests/golden/WBV2-P16-002/manifest.json` |").replace(/\| Current task card \| `[^`]+` \|/u, "| Current task card | `docs/tasks/WBV2-P16-003.md` |").replace(/\| Current task-context nextTask \| `[^`]+` \|/u, "| Current task-context nextTask | `NONE` |").replace(/\| Focused command \| `[^`]+` \|/u, "| Focused command | `node tools/web/generate-wbv2-paint-gate.mjs --write` |"); fs.writeFileSync(absolute("nextTask.md"), nextTask); process.stdout.write(`wbv2-paint-gate-written task=WBV2-P16-003 claims=${claims.length} newlyVerified=2 basePending=6618 effectivePending=6616 remainingPaint=115 repeatedRuns=0 terminal=true artifacts=${Object.keys(artifacts).length}\n`);