import { mkdir, readFile, writeFile } from "node:fs/promises"; import path from "node:path"; /** @param {string} name @param {string} fallback */ function argumentValue(name, fallback) { const index = process.argv.indexOf(name); return index >= 0 && process.argv[index + 1] ? process.argv[index + 1] : fallback; } const policyPath = argumentValue( "--policy", "config/testing/risk-coverage.json", ); const summaryPath = argumentValue( "--summary", "artifacts/tests/coverage/coverage-summary.json", ); const artifactPath = argumentValue( "--artifact", "artifacts/quality/risk-coverage.json", ); const policy = JSON.parse(await readFile(policyPath, "utf8")); const summary = JSON.parse(await readFile(summaryPath, "utf8")); const failures = []; /** @type {Array<{ * scope: string, * metric: string, * threshold: number, * received: number | undefined, * passed: boolean * }>} */ const results = []; /** * @param {string} scope * @param {Record} actual * @param {Record} minimum */ function evaluate(scope, actual, minimum) { for (const [metric, threshold] of Object.entries(minimum)) { const received = actual?.[metric]?.pct; const passed = typeof received === "number" && Number.isFinite(received) && received >= threshold; results.push({ scope, metric, threshold, received, passed }); if (!passed) { failures.push( `${scope}.${metric} expected >= ${threshold}, received ${String(received)}`, ); } } } evaluate("total", summary.total, policy.summary); for (const modulePolicy of policy.criticalModules) { const key = Object.keys(summary).find( (candidate) => candidate !== "total" && candidate.replaceAll("\\", "/").endsWith(`/${modulePolicy.path}`), ); if (!key) { failures.push(`critical module missing from coverage: ${modulePolicy.path}`); continue; } evaluate(modulePolicy.path, summary[key], modulePolicy.minimum); } const artifact = { schemaVersion: 1, policy: policyPath, summary: summaryPath, status: failures.length === 0 ? "PASS" : "FAIL", results, failures, }; await mkdir(path.dirname(artifactPath), { recursive: true }); await writeFile(artifactPath, `${JSON.stringify(artifact, null, 2)}\n`); if (failures.length > 0) { process.stderr.write(`Risk coverage failed:\n- ${failures.join("\n- ")}\n`); process.exit(1); } process.stdout.write( `Risk coverage: PASS (${results.length} scoped thresholds)\n`, );