/home/techb158/balavpn.abdallabala.com/.next/cache/webpack/server-production
NameSizeModeActions
0.pack75919080666editdlrm
1.pack13755910666editdlrm
2.pack2103570666editdlrm
3.pack435023240666editdlrm
4.pack8831030666editdlrm
5.pack2236720666editdlrm
6.pack124000666editdlrm
7.pack1863090666editdlrm
8.pack2143630666editdlrm
9.pack7358150666editdlrm
10.pack2358320666editdlrm
11.pack30785860666editdlrm
12.pack33078460666editdlrm
index.pack85782510666editdlrm
index.pack.old85783080666editdlrm
Edit: /home/techb158/balavpn.abdallabala.com/.next/cache/webpack/server-production/8.pack (214363B)
wpcOE§webpack/lib/cache/PackFileCacheStrategyPackContentItems €¦Compilation/modules|javascript/auto|C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.js!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js??ruleSet[1].rules[16].oneOf[4].use[0]!C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\domain\risk-engine.js|rscœCompilation/assets|chunk6930MinifierWebpackPlugin|6930.js˜webpack/lib/NormalModule«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceê2"use strict"; const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks }; € javascript/autoƒrscœC:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\domain€…aliasŠmainFieldsŽconditionNamesŽfullySpecified`$Œserver-only$Œclient-only$Ÿnext/dist/compiled/server-only$Ÿnext/dist/compiled/client-only$«C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\head.js¬C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\image.js°C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\constants.js­C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\router.js®C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dynamic.js­C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\script.js«C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\link.js«C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\form.js±C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\navigation.js®C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\headers.js©C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\og.js­C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\server.js¯C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\document.jsªC:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\app.js†react$—react/compiler-runtime$–react/jsx-dev-runtime$’react/jsx-runtime$Šreact-dom$‘react-dom/client$‘react-dom/server$™react-dom/server.browser$–react-dom/server.edge$‘react-dom/static$™react-dom/static.browser$–react-dom/static.edge$ react-server-dom-webpack/client$ react-server-dom-webpack/server$¥react-server-dom-webpack/server.node$ react-server-dom-webpack/static$É@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client.ts„next¤next/dist/compiled/server-only/empty¤next/dist/compiled/client-only/errorþÿ¥next/dist/client/components/noop-head“next/dist/api/image—next/dist/api/constants”next/dist/api/router™next/dist/api/app-dynamic”next/dist/api/scriptnext/dist/client/app-dir/linknext/dist/client/app-dir/form¥next/dist/api/navigation.react-server•next/dist/api/headersnext/dist/api/og”next/dist/api/server–next/dist/api/document‘next/dist/api/appºnext/dist/server/route-modules/app-page/vendored/rsc/reactËnext/dist/server/route-modules/app-page/vendored/rsc/react-compiler-runtimeÊnext/dist/server/route-modules/app-page/vendored/rsc/react-jsx-dev-runtimeÆnext/dist/server/route-modules/app-page/vendored/rsc/react-jsx-runtime¾next/dist/server/route-modules/app-page/vendored/rsc/react-dom£next/dist/compiled/react-dom/client¨next/dist/compiled/react-dom/server.node«next/dist/compiled/react-dom/server.browser±next/dist/build/webpack/alias/react-dom-server.js¨next/dist/compiled/react-dom/static.node«next/dist/compiled/react-dom/static.browser¨next/dist/compiled/react-dom/static.edge·next/dist/compiled/react-server-dom-webpack/client.nodeÔnext/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-serverÿÔnext/dist/server/route-modules/app-page/vendored/rsc/react-server-dom-webpack-static§next/dist/client/dev/noop-turbopack-hmr£C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next†module„mainŒreact-serverƒ... ¨`‰cacheable†parsedfileDependencies“contextDependencies“missingDependencies‘buildDependencies‘valueDependencies„hash†assetsŠassetsInfo¡†strict”topLevelDeclarationsˆsnapshot ˜webpack/lib/util/LazySetÚC:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-flight-loader\index.jsÑC:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\node_modules\next\dist\build\webpack\loaders\next-swc-loader.js™webpack/DefinePlugin_hashˆb5546ded345f7990784ae20b„type‰actionIdsŠclientRefsclientEntryType‹isClientRef†server  €`…clampnormalizeStatus—normalizeApprovalStatusˆgetLevel‰scoreRisk‡average’selectedExperiment”riskMitigationRollup‘scoreProjectRisks•calculateOverallScoredimensionScoreslifecycleScores”mitigationCompletionŒevaluateGate’calculateDashboardŠDIMENSIONS†LEVELSšwebpack/lib/FileSystemInfoˆSnapshot ¶÷óyB«C:\Users\abd_b\OneDrive\Desktop\COSMIC AI-Risk Dashboard\Step 12 is complete Final QA, Demo Readiness, and Submission Freeze\application\saas-app\src\domain\risk-engine.jsˆsafeTime‰timestampÔ!àóóóyBÐóóóyB8edb17f240cfc0f6¨webpack/lib/dependencies/ConstDependency€`  ` ¸webpack/lib/dependencies/CommonJsSelfReferenceDependencyAL2Z2Žmodule.exports@@`«webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource r%«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€`«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceJexports.id = 6930; exports.ids = [6930]; exports.modules = { /***/ 2488: «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource — «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource$/***/ ((module) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourcel"use strict"; function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson }; ` €€†buffer†source„size„maps„hash_ function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson }; €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourcel"use strict"; function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson };  012undefined /***/ }) €†buffer†source„size„maps„hash/***/ ((module) => { "use strict"; function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson }; /***/ }) €”{"finalSource":true}ƒmap‹bufferedMap ConcatSourceRawSource$/***/ ((module) => { "use strict"; ReplaceSourceRawSourcel"use strict"; function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson };  012undefined RawSource /***/ }), /***/ 2773:  ‹#«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource ¨ «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceÍ "use strict"; const { prisma } = require("./prisma"); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = require("../domain/permissions"); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; d !')2C(.0F€“__webpack_require__„7964þ„5707€†buffer†source„size„maps„hash¿ const { prisma } = __webpack_require__(7964); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = __webpack_require__(5707); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceÍ "use strict"; const { prisma } = require("./prisma"); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = require("../domain/permissions"); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; v012undefined3339__webpack_require__undefined41507964undefined20882094__webpack_require__undefined209621185707undefined /***/ }) ì /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; const { prisma } = __webpack_require__(7964); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = __webpack_require__(5707); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; /***/ }) íð ñS/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; òÍ "use strict"; const { prisma } = require("./prisma"); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = require("../domain/permissions"); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; v012undefined3339__webpack_require__undefined41507964undefined20882094__webpack_require__undefined209621185707undefinedóô, /***/ 3421:  ÿ(«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource Û «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourcevar __webpack_unused_export__; «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSourceù "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "sendResponse", { enumerable: true, get: function() { return sendResponse; } }); const _helpers = require("./base-http/helpers"); const _pipereadable = require("./pipe-readable"); const _utils = require("./web/utils"); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map h :NNQOÒÒæìî"$4GMO[0R€__webpack_unused_export__ = ()¥Object.defineProperty(exports, "I", (‚))“__webpack_require__„1237þ„5088ý„7679… true€†buffer†source„size„maps„hashÑ var __webpack_unused_export__; __webpack_unused_export__ = ({ value: true }); Object.defineProperty(exports, "I", ({ enumerable: true, get: function() { return sendResponse; } })); const _helpers = __webpack_require__(1237); const _pipereadable = __webpack_require__(5088); const _utils = __webpack_require__(7679); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. true && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map €”{"finalSource":true}ƒmap‹bufferedMap ConcatSourceRawSourcevar __webpack_unused_export__; ReplaceSourceRawSourceù "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "sendResponse", { enumerable: true, get: function() { return sendResponse; } }); const _helpers = require("./base-http/helpers"); const _pipereadable = require("./pipe-readable"); const _utils = require("./web/utils"); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map;012undefined1458__webpack_unused_export__ = (undefined7878)undefined81127Object.defineProperty(exports, "I", (undefined210210))undefined230236__webpack_require__undefined2382581237undefined284290__webpack_require__undefined2923085088undefined327333__webpack_require__undefined3353477679undefined560594 trueundefined /***/ }) á. /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; var __webpack_unused_export__; __webpack_unused_export__ = ({ value: true }); Object.defineProperty(exports, "I", ({ enumerable: true, get: function() { return sendResponse; } })); const _helpers = __webpack_require__(1237); const _pipereadable = __webpack_require__(5088); const _utils = __webpack_require__(7679); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. true && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map /***/ }) âå  æS/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; åvar __webpack_unused_export__; æù "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "sendResponse", { enumerable: true, get: function() { return sendResponse; } }); const _helpers = require("./base-http/helpers"); const _pipereadable = require("./pipe-readable"); const _utils = require("./web/utils"); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map;012undefined1458__webpack_unused_export__ = (undefined7878)undefined81127Object.defineProperty(exports, "I", (undefined210210))undefined230236__webpack_require__undefined2382581237undefined284290__webpack_require__undefined2923085088undefined327333__webpack_require__undefined3353477679undefined560594 trueundefinedçè, /***/ 5400:  «webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource "«webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceP"use strict"; const { prisma } = require("./prisma"); const { hasPermission, canAccessWorkspace } = require("../domain/permissions"); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; g !')2djl@‚€“__webpack_require__„7964þ„5707€†buffer†source„size„maps„hashB const { prisma } = __webpack_require__(7964); const { hasPermission, canAccessWorkspace } = __webpack_require__(5707); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceP"use strict"; const { prisma } = require("./prisma"); const { hasPermission, canAccessWorkspace } = require("../domain/permissions"); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; r012undefined3339__webpack_require__undefined41507964undefined100106__webpack_require__undefined1081305707undefined /***/ }) ÕŸ/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; const { prisma } = __webpack_require__(7964); const { hasPermission, canAccessWorkspace } = __webpack_require__(5707); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; /***/ }) ÖÙ ÚéÜP"use strict"; const { prisma } = require("./prisma"); const { hasPermission, canAccessWorkspace } = require("../domain/permissions"); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; r012undefined3339__webpack_require__undefined41507964undefined100106__webpack_require__undefined1081305707undefinedÝÞ, /***/ 5567:  ›«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource$/***/ ((module) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource Œ3«webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceê2"use strict"; const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks }; ` €€†buffer†source„size„maps„hashÝ2 const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks }; €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceê2"use strict"; const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks };  012undefined /***/ }) Ë 3/***/ ((module) => { "use strict"; const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks }; /***/ }) ÌÏ ÐÑÒê2"use strict"; const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks }; ÓÔÕ, /***/ 5707:  },«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource$/***/ ((module) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource °«webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource"use strict"; const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk }; ` €€†buffer†source„size„maps„hash const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk }; €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSource"use strict"; const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk };  012undefined /***/ }) Â//***/ ((module) => { "use strict"; const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk }; /***/ }) ÃÆ ÇÈÉ"use strict"; const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk }; ÊËÌ, /***/ 5736:  ‚«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource }«webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceR"use strict"; if (process.env.NEXT_RUNTIME === 'edge') { module.exports = require('next/dist/server/route-modules/app-route/module.js'); } else { if (process.env.__NEXT_EXPERIMENTAL_REACT) { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js'); } } } else { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js'); } } } } //# sourceMappingURL=module.compiled.js.map  c 47NžÂÅŠŸÄÇí—°€…false‚{}þÿþÿþÿªmodule.exports = __webpack_require__(4870)€†buffer†source„size„maps„hashõ if (false) {} else { if (false) {} else { if (false) {} else { if (false) {} else { module.exports = __webpack_require__(4870); } } } } //# sourceMappingURL=module.compiled.js.map €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceR"use strict"; if (process.env.NEXT_RUNTIME === 'edge') { module.exports = require('next/dist/server/route-modules/app-route/module.js'); } else { if (process.env.__NEXT_EXPERIMENTAL_REACT) { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js'); } } } else { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js'); } } } } //# sourceMappingURL=module.compiled.js.mapÝ012undefined1852falseundefined55141{}undefined158194falseundefined197906{}undefined927964falseundefined9671261{}undefined12861306falseundefined13091431{}undefined14561539module.exports = __webpack_require__(4870)undefined /***/ }) ¹R/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; if (false) {} else { if (false) {} else { if (false) {} else { if (false) {} else { module.exports = __webpack_require__(4870); } } } } //# sourceMappingURL=module.compiled.js.map /***/ }) º½ ¾ÍÀR"use strict"; if (process.env.NEXT_RUNTIME === 'edge') { module.exports = require('next/dist/server/route-modules/app-route/module.js'); } else { if (process.env.__NEXT_EXPERIMENTAL_REACT) { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js'); } } } else { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js'); } } } } //# sourceMappingURL=module.compiled.js.mapÝ012undefined1852falseundefined55141{}undefined158194falseundefined197906{}undefined927964falseundefined9671261{}undefined12861306falseundefined13091431{}undefined14561539module.exports = __webpack_require__(4870)undefinedÁÂ, /***/ 6487:  4«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource/***/ (() => { «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource €†buffer†source„size„maps„hash €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceÿ /***/ }) ¯/***/ (() => { /***/ }) °³ ´/***/ (() => { µÿ·¸, /***/ 7964:  -«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSourceS/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource ý«webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource "use strict"; const { PrismaClient } = require("@prisma/client"); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if ("production" !== "production") { globalForPrisma.__cosmicPrisma = prisma; } module.exports = { prisma }; d '-/>C¯ËÎý€“__webpack_require__„6330…false‚{}€†buffer†source„size„maps„hashÍ const { PrismaClient } = __webpack_require__(6330); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if (false) {} module.exports = { prisma }; €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSource "use strict"; const { PrismaClient } = require("@prisma/client"); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if ("production" !== "production") { globalForPrisma.__cosmicPrisma = prisma; } module.exports = { prisma }; b012undefined3945__webpack_require__undefined47626330undefined175203falseundefined206253{}undefined /***/ }) ¥*/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; const { PrismaClient } = __webpack_require__(6330); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if (false) {} module.exports = { prisma }; /***/ }) ¦© ª¹¬ "use strict"; const { PrismaClient } = require("@prisma/client"); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if ("production" !== "production") { globalForPrisma.__cosmicPrisma = prisma; } module.exports = { prisma }; b012undefined3945__webpack_require__undefined47626330undefined175203falseundefined206253{}undefined­®, /***/ 8335:  4«webpack/lib/util/registerExternalSerializerœwebpack-sources/ConcatSource€«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource/***/ (() => { «webpack/lib/util/registerExternalSerializerœwebpack-sources/CachedSource «webpack/lib/util/registerExternalSerializerwebpack-sources/ReplaceSource«webpack/lib/util/registerExternalSerializer™webpack-sources/RawSource €†buffer†source„size„maps„hash €”{"finalSource":true}ƒmap‹bufferedMap ReplaceSourceRawSourceÿ /***/ }) ›ì   ¡í£î }; ; †buffer†source„size„mapsÀ7eexports.id = 6930; exports.ids = [6930]; exports.modules = { /***/ 2488: /***/ ((module) => { "use strict"; function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson }; /***/ }), /***/ 2773: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; const { prisma } = __webpack_require__(7964); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = __webpack_require__(5707); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; /***/ }), /***/ 3421: /***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; var __webpack_unused_export__; __webpack_unused_export__ = ({ value: true }); Object.defineProperty(exports, "I", ({ enumerable: true, get: function() { return sendResponse; } })); const _helpers = __webpack_require__(1237); const _pipereadable = __webpack_require__(5088); const _utils = __webpack_require__(7679); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. true && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map /***/ }), /***/ 5400: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; const { prisma } = __webpack_require__(7964); const { hasPermission, canAccessWorkspace } = __webpack_require__(5707); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; /***/ }), /***/ 5567: /***/ ((module) => { "use strict"; const DIMENSIONS = [ "Organizational", "Technical", "Human" ]; const LEVELS = [ { name: "Low", min: 0, max: 24 }, { name: "Moderate", min: 25, max: 49 }, { name: "High", min: 50, max: 74 }, { name: "Critical", min: 75, max: 100 } ]; function clamp(value, min, max) { return Math.max(min, Math.min(max, Number(value) || 0)); } function normalizeStatus(status) { return String(status || "OPEN").replace(/_/g, " ").toLowerCase(); } function normalizeApprovalStatus(status) { return String(status || "PENDING").replace(/_/g, " ").toLowerCase(); } function getLevel(score) { const bounded = clamp(score, 0, 100); const level = LEVELS.find((item)=>bounded >= item.min && bounded <= item.max); return level ? level.name : "Unknown"; } function scoreRisk(risk) { const probability = clamp(risk.probability, 1, 5); const impact = clamp(risk.impact, 1, 5); const detectability = clamp(risk.detectability, 1, 5); const mitigationProgress = clamp(risk.mitigationProgress ?? risk.mitigation_progress ?? risk.progressPercent ?? 0, 0, 100); const mitigationEffectiveness = clamp(risk.mitigationEffectiveness ?? risk.mitigation_effectiveness ?? risk.effectivenessPercent ?? 0, 0, 100); const rawScore = probability * impact * detectability; const normalizedScore = Math.round(rawScore / 125 * 100); const reduction = mitigationProgress / 100 * (mitigationEffectiveness / 100); const residualScore = normalizeStatus(risk.status) === "closed" ? Math.round(normalizedScore * 0.1) : Math.round(normalizedScore * (1 - reduction)); return Object.assign({}, risk, { probability, impact, detectability, mitigationProgress, mitigationEffectiveness, rawScore, normalizedScore, residualScore: clamp(residualScore, 0, 100), severity: getLevel(normalizedScore), residualSeverity: getLevel(residualScore) }); } function average(values) { const clean = values.filter((value)=>Number.isFinite(Number(value))); if (!clean.length) return 0; return Math.round(clean.reduce((sum, value)=>sum + Number(value), 0) / clean.length); } function selectedExperiment(experiments) { return experiments.find((item)=>item.selected) || experiments[0] || null; } function riskMitigationRollup(risk) { const mitigations = risk.mitigations || []; if (!mitigations.length) return { mitigationProgress: 0, mitigationEffectiveness: 0 }; return { mitigationProgress: average(mitigations.map((item)=>item.progressPercent)), mitigationEffectiveness: average(mitigations.map((item)=>item.effectivenessPercent)) }; } function scoreProjectRisks(risks) { return risks.map((risk)=>scoreRisk(Object.assign({}, risk, riskMitigationRollup(risk)))); } function calculateOverallScore(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); if (!active.length) return 0; const topRisks = active.slice().sort((a, b)=>b.normalizedScore - a.normalizedScore).slice(0, 8); const avgTopNormalized = average(topRisks.map((risk)=>risk.normalizedScore)); const avgTopResidual = average(topRisks.map((risk)=>risk.residualScore)); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const highUnapproved = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const approvalPenalty = Math.min(12, highUnapproved * 2) + Math.min(15, criticalOpen * 4); const exposure = Math.round(avgTopNormalized * 0.7 + avgTopResidual * 0.3); return clamp(exposure + approvalPenalty, 0, 100); } function dimensionScores(scoredRisks) { return DIMENSIONS.map((dimension)=>{ const risks = scoredRisks.filter((risk)=>risk.dimension === dimension && normalizeStatus(risk.status) !== "closed"); return { name: dimension, score: average(risks.map((risk)=>risk.residualScore)) }; }); } function lifecycleScores(lifecyclePhases, scoredRisks) { return lifecyclePhases.map((phase)=>{ const phaseRisks = scoredRisks.filter((risk)=>risk.lifecyclePhase === phase.name && normalizeStatus(risk.status) !== "closed"); const riskScore = average(phaseRisks.map((risk)=>risk.residualScore)); return Object.assign({}, phase, { openRisks: phaseRisks.length, riskScore, riskLevel: getLevel(riskScore) }); }); } function mitigationCompletion(scoredRisks) { const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return average(active.map((risk)=>risk.mitigationProgress)); } function evaluateGate(project, scoredRisks, experiments, overallScore, mitigationPct) { const thresholds = project.thresholds || {}; const reviews = project.reviews || {}; const selected = selectedExperiment(experiments || []); const active = scoredRisks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); const criticalOpen = active.filter((risk)=>risk.normalizedScore >= 75 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const unapprovedHigh = active.filter((risk)=>risk.normalizedScore >= 50 && ![ "accepted", "approved" ].includes(normalizeApprovalStatus(risk.approvalStatus))).length; const selectedF1 = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "f1") : null; const selectedStability = selected && selected.metrics ? selected.metrics.find((metric)=>metric.metricName === "stability") : null; const criteria = [ { name: "Overall risk score", required: `<= ${thresholds.overallRiskMax ?? 50}`, actual: overallScore, status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked", blocking: overallScore > (thresholds.overallRiskMax ?? 50), evidence: "Calculated from residual active risks and approval penalty." }, { name: "Open critical risks", required: `<= ${thresholds.criticalOpenMax ?? 0}`, actual: criticalOpen, status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked", blocking: criticalOpen > (thresholds.criticalOpenMax ?? 0), evidence: "Critical risks must be closed, accepted, or approved." }, { name: "Mitigation completeness", required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`, actual: `${mitigationPct}%`, status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked", blocking: mitigationPct < (thresholds.mitigationCompletionMin ?? 60), evidence: "Average mitigation progress across active risks." }, { name: "Data readiness", required: `>= ${thresholds.dataReadinessMin ?? 70}`, actual: reviews.dataReadiness ? reviews.dataReadiness.score : "Missing", status: reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70) ? "Pass" : "Blocked", blocking: !(reviews.dataReadiness && reviews.dataReadiness.score >= (thresholds.dataReadinessMin ?? 70)), evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing." }, { name: "Selected model performance", required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`, actual: selectedF1 ? selectedF1.metricValue : "Missing", status: selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked", blocking: !(selectedF1 && selectedF1.metricValue >= (thresholds.selectedModelF1Min ?? 0.8)), evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment." }, { name: "Selected model stability", required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`, actual: selectedStability ? selectedStability.metricValue : "Missing", status: selectedStability && selectedStability.metricValue >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning", blocking: false, evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment." }, { name: "Ethical review", required: "Approved or Accepted", actual: reviews.ethicalReview ? reviews.ethicalReview.status : "Missing", status: reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.ethicalReview && [ "Approved", "Accepted" ].includes(reviews.ethicalReview.status)), evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing." }, { name: "Legal review", required: "Approved or Accepted", actual: reviews.legalReview ? reviews.legalReview.status : "Missing", status: reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status) ? "Pass" : "Blocked", blocking: !(reviews.legalReview && [ "Approved", "Accepted" ].includes(reviews.legalReview.status)), evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing." }, { name: "High-risk approval state", required: "No unapproved high risks", actual: unapprovedHigh, status: unapprovedHigh === 0 ? "Pass" : "Blocked", blocking: unapprovedHigh !== 0, evidence: "High risks require owner approval, acceptance, closure, or documented treatment." } ]; const blocked = criteria.filter((item)=>item.status === "Blocked"); const warnings = criteria.filter((item)=>item.status === "Warning"); const status = blocked.length ? "BLOCKED" : warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35) ? "WARNING" : "READY"; return { status, criteria, blockedCount: blocked.length, warningCount: warnings.length, message: status === "BLOCKED" ? `Deployment gate blocked by ${blocked.length} criterion or criteria.` : status === "WARNING" ? "Deployment gate requires reviewer attention before release." : "Deployment gate is ready." }; } function calculateDashboard(project) { const risks = scoreProjectRisks(project.risks || []); const mitigationPct = mitigationCompletion(risks); const overallScore = calculateOverallScore(risks); const gate = evaluateGate(project, risks, project.experiments || [], overallScore, mitigationPct); const active = risks.filter((risk)=>normalizeStatus(risk.status) !== "closed"); return { project: { id: project.id, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate }, summary: { overallScore, riskLevel: getLevel(overallScore), gateStatus: gate.status, openRisks: active.length, totalRisks: risks.length, highRisks: active.filter((risk)=>risk.normalizedScore >= 50 && risk.normalizedScore < 75).length, criticalRisks: active.filter((risk)=>risk.normalizedScore >= 75).length, mitigationCompletion: mitigationPct }, dimensions: dimensionScores(risks), lifecycle: lifecycleScores(project.lifecyclePhases || [], risks), gate, scoredRisks: risks, topRisks: active.slice().sort((a, b)=>b.residualScore - a.residualScore).slice(0, 8), mitigations: risks.flatMap((risk)=>(risk.mitigations || []).map((mitigation)=>Object.assign({}, mitigation, { riskTitle: risk.title, riskResidualScore: risk.residualScore }))), indicators: project.indicators || [], experiments: project.experiments || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks }; /***/ }), /***/ 5707: /***/ ((module) => { "use strict"; const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk }; /***/ }), /***/ 5736: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; if (false) {} else { if (false) {} else { if (false) {} else { if (false) {} else { module.exports = __webpack_require__(4870); } } } } //# sourceMappingURL=module.compiled.js.map /***/ }), /***/ 6487: /***/ (() => { /***/ }), /***/ 7964: /***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; const { PrismaClient } = __webpack_require__(6330); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if (false) {} module.exports = { prisma }; /***/ }), /***/ 8335: /***/ (() => { /***/ }) }; ;  ‚{}ƒmap‹bufferedMap `^ConcatSourceRawSourceJexports.id = 6930; exports.ids = [6930]; exports.modules = { /***/ 2488: þ$/***/ ((module) => { "use strict"; ReplaceSourceRawSourcel"use strict"; function jsonResponse(payload, status = 200, headers = {}) { return Response.json(payload, { status, headers: Object.assign({ "Cache-Control": "no-store" }, headers) }); } function errorResponse(error) { return jsonResponse({ error: error.message || "Unexpected error", details: error.details || undefined }, error.status || 500); } async function parseJson(request) { const text = await request.text(); if (!text) return {}; return JSON.parse(text); } module.exports = { jsonResponse, errorResponse, parseJson };  012undefined RawSource /***/ })þ, /***/ 2773: ÷S/***/ ((module, __unused_webpack_exports, __webpack_require__) => { "use strict"; ùÍ "use strict"; const { prisma } = require("./prisma"); async function getActorFromRequest(request) { const cookie = request.headers.get("cookie") || ""; const sessionMatch = cookie.match(/cosmic_session=([^;]+)/); if (sessionMatch) { const session = await prisma.session.findUnique({ where: { token: sessionMatch[1] }, include: { user: { include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } } } }); if (session && session.expiresAt > new Date()) { return session.user; } if (session) { await prisma.session.delete({ where: { id: session.id } }).catch(()=>{}); } } const email = request.headers.get("x-cosmic-user-email") || process.env.COSMIC_BOOTSTRAP_EMAIL || "owner@cosmic.local"; const user = await prisma.user.findUnique({ where: { email }, include: { memberships: { where: { status: "ACTIVE" }, include: { role: true, organization: true } } } }); if (!user) { const error = new Error(`Unknown actor: ${email}`); error.status = 401; throw error; } return user; } function getMembership(actor, organizationId) { return actor.memberships.find((item)=>item.organizationId === organizationId && item.status === "ACTIVE"); } async function requireOrganizationActor(request, organizationId, permission = "project:read") { const { hasPermission } = require("../domain/permissions"); const actor = await getActorFromRequest(request); const membership = getMembership(actor, organizationId); if (!membership) { const error = new Error("Actor is not a member of this organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } return { actor, membership, organization: membership.organization }; } module.exports = { getActorFromRequest, requireOrganizationActor }; v012undefined3339__webpack_require__undefined41507964undefined20882094__webpack_require__undefined209621185707undefinedúûú, /***/ 3421: óS/***/ ((__unused_webpack_module, exports, __webpack_require__) => { "use strict"; òvar __webpack_unused_export__; ôù "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "sendResponse", { enumerable: true, get: function() { return sendResponse; } }); const _helpers = require("./base-http/helpers"); const _pipereadable = require("./pipe-readable"); const _utils = require("./web/utils"); async function sendResponse(req, res, response, waitUntil) { if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextResponse)(res)) { var // Copy over the response headers. _response_headers; // Copy over the response status. res.statusCode = response.status; res.statusMessage = response.statusText; // TODO: this is not spec-compliant behavior and we should not restrict // headers that are allowed to appear many times. // // See: // https://github.com/vercel/next.js/pull/70127 const headersWithMultipleValuesAllowed = [ // can add more headers to this list if needed 'set-cookie', 'www-authenticate', 'proxy-authenticate', 'vary' ]; (_response_headers = response.headers) == null ? void 0 : _response_headers.forEach((value, name)=>{ // `x-middleware-set-cookie` is an internal header not needed for the response if (name.toLowerCase() === 'x-middleware-set-cookie') { return; } // The append handling is special cased for `set-cookie`. if (name.toLowerCase() === 'set-cookie') { // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici for (const cookie of (0, _utils.splitCookiesString)(value)){ res.appendHeader(name, cookie); } } else { // only append the header if it is either not present in the outbound response // or if the header supports multiple values const isHeaderPresent = typeof res.getHeader(name) !== 'undefined'; if (headersWithMultipleValuesAllowed.includes(name.toLowerCase()) || !isHeaderPresent) { res.appendHeader(name, value); } } }); /** * The response can't be directly piped to the underlying response. The * following is duplicated from the edge runtime handler. * * See packages/next/server/next-server.ts */ const { originalResponse } = res; // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { await (0, _pipereadable.pipeToNodeResponse)(response.body, originalResponse, waitUntil); } else { originalResponse.end(); } } } //# sourceMappingURL=send-response.js.map;012undefined1458__webpack_unused_export__ = (undefined7878)undefined81127Object.defineProperty(exports, "I", (undefined210210))undefined230236__webpack_require__undefined2382581237undefined284290__webpack_require__undefined2923085088undefined327333__webpack_require__undefined3353477679undefined560594 trueundefinedõöõ, /***/ 5400: î÷ñP"use strict"; const { prisma } = require("./prisma"); const { hasPermission, canAccessWorkspace } = require("../domain/permissions"); async function getProjectScope(projectId) { const project = await prisma.project.findUnique({ where: { id: projectId }, include: { workspace: { include: { organization: true } } } }); if (!project) { const error = new Error(`Project not found: ${projectId}`); error.status = 404; throw error; } return project; } async function requireProjectAccess(actor, projectId, permission = "project:read") { const project = await getProjectScope(projectId); const membership = actor.memberships.find((item)=>item.organizationId === project.workspace.organizationId && item.status === "ACTIVE"); if (!membership) { const error = new Error("Actor cannot access this project's organization."); error.status = 403; throw error; } if (!hasPermission(membership.role.permissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } if (!canAccessWorkspace(membership, project.workspaceId)) { const error = new Error("Actor cannot access this workspace."); error.status = 403; throw error; } return { project, membership, organization: project.workspace.organization }; } module.exports = { getProjectScope, requireProjectAccess }; r012undefined3339__webpack_require__undefined41507964undefined100106__webpack_require__undefined1081305707undefinedòóò, /***/ 5567: ëíîBÿÿÿðñòñ, /***/ 5707: êìí"use strict"; const PERMISSIONS = [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "report:export", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "billing:manage", "audit:read" ]; const ROLE_PERMISSIONS = { owner: [ "*" ], admin: [ "organization:manage", "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "integration:manage", "billing:manage", "audit:read" ], project_manager: [ "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "report:export", "integration:read", "audit:read" ], risk_owner: [ "project:read", "risk:read", "risk:write", "mitigation:write", "gate:read" ], governance_reviewer: [ "project:read", "risk:read", "gate:evaluate", "gate:review", "report:export", "audit:read" ], legal_ethics_reviewer: [ "project:read", "risk:read", "mitigation:write", "gate:review", "report:export", "audit:read" ], integration_admin: [ "project:read", "integration:read", "integration:manage", "integration:sync", "oauth:manage", "audit:read" ], viewer: [ "project:read", "risk:read", "gate:read", "integration:read", "report:export" ], consultant: [ "workspace:manage", "project:read", "project:write", "risk:read", "risk:write", "mitigation:write", "gate:evaluate", "gate:review", "report:export", "audit:read" ] }; function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function resolvePermissions(roleCodeOrPermissions) { if (Array.isArray(roleCodeOrPermissions)) return unique(roleCodeOrPermissions); return ROLE_PERMISSIONS[roleCodeOrPermissions] ? ROLE_PERMISSIONS[roleCodeOrPermissions].slice() : []; } function hasPermission(roleCodeOrPermissions, permission) { const permissions = resolvePermissions(roleCodeOrPermissions); return permissions.includes("*") || permissions.includes(permission); } function assertPermission(roleCodeOrPermissions, permission) { if (!hasPermission(roleCodeOrPermissions, permission)) { const error = new Error(`Permission denied: ${permission}`); error.status = 403; throw error; } } function canAccessWorkspace(membership, workspaceId) { if (!membership || membership.status !== "ACTIVE") return false; if (!membership.workspaceScope || membership.workspaceScope.length === 0) return true; return membership.workspaceScope.includes(workspaceId); } function canMutateRisk(membership) { return canAccessWorkspace(membership, "workspace-a") && hasPermission(membership.permissions || membership.role?.permissions, "risk:write"); } module.exports = { PERMISSIONS, ROLE_PERMISSIONS, resolvePermissions, hasPermission, assertPermission, canAccessWorkspace, canMutateRisk }; îïðï, /***/ 5736: èñëR"use strict"; if (process.env.NEXT_RUNTIME === 'edge') { module.exports = require('next/dist/server/route-modules/app-route/module.js'); } else { if (process.env.__NEXT_EXPERIMENTAL_REACT) { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo-experimental.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route-experimental.runtime.prod.js'); } } } else { if (process.env.NODE_ENV === 'development') { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.dev.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.dev.js'); } } else { if (process.env.TURBOPACK) { module.exports = require('next/dist/compiled/next-server/app-route-turbo.runtime.prod.js'); } else { module.exports = require('next/dist/compiled/next-server/app-route.runtime.prod.js'); } } } } //# sourceMappingURL=module.compiled.js.mapÝ012undefined1852falseundefined55141{}undefined158194falseundefined197906{}undefined927964falseundefined9671261{}undefined12861306falseundefined13091431{}undefined14561539module.exports = __webpack_require__(4870)undefinedìíì, /***/ 6487: å/***/ (() => { çÿéêé, /***/ 7964: âëå "use strict"; const { PrismaClient } = require("@prisma/client"); const globalForPrisma = globalThis; const prisma = globalForPrisma.__cosmicPrisma || new PrismaClient(); if ("production" !== "production") { globalForPrisma.__cosmicPrisma = prisma; } module.exports = { prisma }; b012undefined3945__webpack_require__undefined47626330undefined175203falseundefined206253{}undefinedæçæ, /***/ 8335: ßúâûûåæå }; ;Ð /exports.id=6930,exports.ids=[6930],exports.modules={2488:a=>{"use strict";function b(a,c=200,d={}){return Response.json(a,{status:c,headers:Object.assign({"Cache-Control":"no-store"},d)})}a.exports={jsonResponse:b,errorResponse:function(a){return b({error:a.message||"Unexpected error",details:a.details||void 0},a.status||500)},parseJson:async function(a){let b=await a.text();return b?JSON.parse(b):{}}}},2773:(a,b,c)=>{"use strict";let{prisma:d}=c(7964);async function e(a){let b=(a.headers.get("cookie")||"").match(/cosmic_session=([^;]+)/);if(b){let a=await d.session.findUnique({where:{token:b[1]},include:{user:{include:{memberships:{where:{status:"ACTIVE"},include:{role:!0,organization:!0}}}}}});if(a&&a.expiresAt>new Date)return a.user;a&&await d.session.delete({where:{id:a.id}}).catch(()=>{})}let c=a.headers.get("x-cosmic-user-email")||process.env.COSMIC_BOOTSTRAP_EMAIL||"owner@cosmic.local",e=await d.user.findUnique({where:{email:c},include:{memberships:{where:{status:"ACTIVE"},include:{role:!0,organization:!0}}}});if(!e){let a=Error(`Unknown actor: ${c}`);throw a.status=401,a}return e}async function f(a,b,d="project:read"){let{hasPermission:g}=c(5707),h=await e(a),i=h.memberships.find(a=>a.organizationId===b&&"ACTIVE"===a.status);if(!i){let a=Error("Actor is not a member of this organization.");throw a.status=403,a}if(!g(i.role.permissions,d)){let a=Error(`Permission denied: ${d}`);throw a.status=403,a}return{actor:h,membership:i,organization:i.organization}}a.exports={getActorFromRequest:e,requireOrganizationActor:f}},3421:(a,b,c)=>{"use strict";Object.defineProperty(b,"I",{enumerable:!0,get:function(){return g}});let d=c(1237),e=c(5088),f=c(7679);async function g(a,b,c,g){if((0,d.isNodeNextResponse)(b)){var h;b.statusCode=c.status,b.statusMessage=c.statusText;let d=["set-cookie","www-authenticate","proxy-authenticate","vary"];null==(h=c.headers)||h.forEach((a,c)=>{if("x-middleware-set-cookie"!==c.toLowerCase())if("set-cookie"===c.toLowerCase())for(let d of(0,f.splitCookiesString)(a))b.appendHeader(c,d);else{let e=void 0!==b.getHeader(c);(d.includes(c.toLowerCase())||!e)&&b.appendHeader(c,a)}});let{originalResponse:i}=b;c.body&&"HEAD"!==a.method?await (0,e.pipeToNodeResponse)(c.body,i,g):i.end()}}},5400:(a,b,c)=>{"use strict";let{prisma:d}=c(7964),{hasPermission:e,canAccessWorkspace:f}=c(5707);async function g(a){let b=await d.project.findUnique({where:{id:a},include:{workspace:{include:{organization:!0}}}});if(!b){let b=Error(`Project not found: ${a}`);throw b.status=404,b}return b}async function h(a,b,c="project:read"){let d=await g(b),i=a.memberships.find(a=>a.organizationId===d.workspace.organizationId&&"ACTIVE"===a.status);if(!i){let a=Error("Actor cannot access this project's organization.");throw a.status=403,a}if(!e(i.role.permissions,c)){let a=Error(`Permission denied: ${c}`);throw a.status=403,a}if(!f(i,d.workspaceId)){let a=Error("Actor cannot access this workspace.");throw a.status=403,a}return{project:d,membership:i,organization:d.workspace.organization}}a.exports={getProjectScope:g,requireProjectAccess:h}},5567:a=>{"use strict";let b=["Organizational","Technical","Human"],c=[{name:"Low",min:0,max:24},{name:"Moderate",min:25,max:49},{name:"High",min:50,max:74},{name:"Critical",min:75,max:100}];function d(a,b,c){return Math.max(b,Math.min(c,Number(a)||0))}function e(a){return String(a||"OPEN").replace(/_/g," ").toLowerCase()}function f(a){return String(a||"PENDING").replace(/_/g," ").toLowerCase()}function g(a){let b=d(a,0,100),e=c.find(a=>b>=a.min&&b<=a.max);return e?e.name:"Unknown"}function h(a){let b=d(a.probability,1,5),c=d(a.impact,1,5),f=d(a.detectability,1,5),h=d(a.mitigationProgress??a.mitigation_progress??a.progressPercent??0,0,100),i=d(a.mitigationEffectiveness??a.mitigation_effectiveness??a.effectivenessPercent??0,0,100),j=b*c*f,k=Math.round(j/125*100),l=h/100*(i/100),m="closed"===e(a.status)?Math.round(.1*k):Math.round(k*(1-l));return Object.assign({},a,{probability:b,impact:c,detectability:f,mitigationProgress:h,mitigationEffectiveness:i,rawScore:j,normalizedScore:k,residualScore:d(m,0,100),severity:g(k),residualSeverity:g(m)})}function i(a){let b=a.filter(a=>Number.isFinite(Number(a)));return b.length?Math.round(b.reduce((a,b)=>a+Number(b),0)/b.length):0}function j(a){return a.map(a=>h(Object.assign({},a,function(a){let b=a.mitigations||[];return b.length?{mitigationProgress:i(b.map(a=>a.progressPercent)),mitigationEffectiveness:i(b.map(a=>a.effectivenessPercent))}:{mitigationProgress:0,mitigationEffectiveness:0}}(a))))}function k(a){let b=a.filter(a=>"closed"!==e(a.status));if(!b.length)return 0;let c=b.slice().sort((a,b)=>b.normalizedScore-a.normalizedScore).slice(0,8),g=i(c.map(a=>a.normalizedScore)),h=i(c.map(a=>a.residualScore)),j=b.filter(a=>a.normalizedScore>=75&&!["accepted","approved"].includes(f(a.approvalStatus))).length;return d(Math.round(.7*g+.3*h)+(Math.min(12,2*b.filter(a=>a.normalizedScore>=50&&!["accepted","approved"].includes(f(a.approvalStatus))).length)+Math.min(15,4*j)),0,100)}function l(a,b,c,d,g){var h;let i=a.thresholds||{},j=a.reviews||{},k=(h=c||[]).find(a=>a.selected)||h[0]||null,l=b.filter(a=>"closed"!==e(a.status)),m=l.filter(a=>a.normalizedScore>=75&&!["accepted","approved"].includes(f(a.approvalStatus))).length,n=l.filter(a=>a.normalizedScore>=50&&!["accepted","approved"].includes(f(a.approvalStatus))).length,o=k&&k.metrics?k.metrics.find(a=>"f1"===a.metricName):null,p=k&&k.metrics?k.metrics.find(a=>"stability"===a.metricName):null,q=[{name:"Overall risk score",required:`<= ${i.overallRiskMax??50}`,actual:d,status:d<=(i.overallRiskMax??50)?"Pass":"Blocked",blocking:d>(i.overallRiskMax??50),evidence:"Calculated from residual active risks and approval penalty."},{name:"Open critical risks",required:`<= ${i.criticalOpenMax??0}`,actual:m,status:m<=(i.criticalOpenMax??0)?"Pass":"Blocked",blocking:m>(i.criticalOpenMax??0),evidence:"Critical risks must be closed, accepted, or approved."},{name:"Mitigation completeness",required:`>= ${i.mitigationCompletionMin??60}%`,actual:`${g}%`,status:g>=(i.mitigationCompletionMin??60)?"Pass":"Blocked",blocking:g<(i.mitigationCompletionMin??60),evidence:"Average mitigation progress across active risks."},{name:"Data readiness",required:`>= ${i.dataReadinessMin??70}`,actual:j.dataReadiness?j.dataReadiness.score:"Missing",status:j.dataReadiness&&j.dataReadiness.score>=(i.dataReadinessMin??70)?"Pass":"Blocked",blocking:!(j.dataReadiness&&j.dataReadiness.score>=(i.dataReadinessMin??70)),evidence:j.dataReadiness?j.dataReadiness.evidence:"Data readiness review missing."},{name:"Selected model performance",required:`F1 >= ${i.selectedModelF1Min??.8}`,actual:o?o.metricValue:"Missing",status:o&&o.metricValue>=(i.selectedModelF1Min??.8)?"Pass":"Blocked",blocking:!(o&&o.metricValue>=(i.selectedModelF1Min??.8)),evidence:k?`${k.name} selected for gate review.`:"No selected experiment."},{name:"Selected model stability",required:`>= ${i.selectedModelStabilityMin??75}`,actual:p?p.metricValue:"Missing",status:p&&p.metricValue>=(i.selectedModelStabilityMin??75)?"Pass":"Warning",blocking:!1,evidence:k?"Stability is based on repeated evaluation variation.":"No selected experiment."},{name:"Ethical review",required:"Approved or Accepted",actual:j.ethicalReview?j.ethicalReview.status:"Missing",status:j.ethicalReview&&["Approved","Accepted"].includes(j.ethicalReview.status)?"Pass":"Blocked",blocking:!(j.ethicalReview&&["Approved","Accepted"].includes(j.ethicalReview.status)),evidence:j.ethicalReview?j.ethicalReview.evidence:"Ethical review missing."},{name:"Legal review",required:"Approved or Accepted",actual:j.legalReview?j.legalReview.status:"Missing",status:j.legalReview&&["Approved","Accepted"].includes(j.legalReview.status)?"Pass":"Blocked",blocking:!(j.legalReview&&["Approved","Accepted"].includes(j.legalReview.status)),evidence:j.legalReview?j.legalReview.evidence:"Legal review missing."},{name:"High-risk approval state",required:"No unapproved high risks",actual:n,status:0===n?"Pass":"Blocked",blocking:0!==n,evidence:"High risks require owner approval, acceptance, closure, or documented treatment."}],r=q.filter(a=>"Blocked"===a.status),s=q.filter(a=>"Warning"===a.status),t=r.length?"BLOCKED":s.length||d>=(i.gateWarningScore??35)?"WARNING":"READY";return{status:t,criteria:q,blockedCount:r.length,warningCount:s.length,message:"BLOCKED"===t?`Deployment gate blocked by ${r.length} criterion or criteria.`:"WARNING"===t?"Deployment gate requires reviewer attention before release.":"Deployment gate is ready."}}a.exports={DIMENSIONS:b,scoreRisk:h,getLevel:g,calculateDashboard:function(a){var c;let d=j(a.risks||[]),f=i(d.filter(a=>"closed"!==e(a.status)).map(a=>a.mitigationProgress)),h=k(d),m=l(a,d,a.experiments||[],h,f),n=d.filter(a=>"closed"!==e(a.status));return{project:{id:a.id,name:a.name,subtitle:a.subtitle,status:a.status,assessmentDate:a.assessmentDate},summary:{overallScore:h,riskLevel:g(h),gateStatus:m.status,openRisks:n.length,totalRisks:d.length,highRisks:n.filter(a=>a.normalizedScore>=50&&a.normalizedScore<75).length,criticalRisks:n.filter(a=>a.normalizedScore>=75).length,mitigationCompletion:f},dimensions:b.map(a=>{let b=d.filter(b=>b.dimension===a&&"closed"!==e(b.status));return{name:a,score:i(b.map(a=>a.residualScore))}}),lifecycle:(c=a.lifecyclePhases||[],c.map(a=>{let b=d.filter(b=>b.lifecyclePhase===a.name&&"closed"!==e(b.status)),c=i(b.map(a=>a.residualScore));return Object.assign({},a,{openRisks:b.length,riskScore:c,riskLevel:g(c)})})),gate:m,scoredRisks:d,topRisks:n.slice().sort((a,b)=>b.residualScore-a.residualScore).slice(0,8),mitigations:d.flatMap(a=>(a.mitigations||[]).map(b=>Object.assign({},b,{riskTitle:a.title,riskResidualScore:a.residualScore}))),indicators:a.indicators||[],experiments:a.experiments||[]}},evaluateGate:l,calculateOverallScore:k,scoreProjectRisks:j}},5707:a=>{"use strict";let b={owner:["*"],admin:["organization:manage","workspace:manage","project:read","project:write","risk:read","risk:write","risk:delete","mitigation:write","gate:evaluate","gate:review","report:export","integration:manage","billing:manage","audit:read"],project_manager:["project:read","project:write","risk:read","risk:write","mitigation:write","gate:evaluate","report:export","integration:read","audit:read"],risk_owner:["project:read","risk:read","risk:write","mitigation:write","gate:read"],governance_reviewer:["project:read","risk:read","gate:evaluate","gate:review","report:export","audit:read"],legal_ethics_reviewer:["project:read","risk:read","mitigation:write","gate:review","report:export","audit:read"],integration_admin:["project:read","integration:read","integration:manage","integration:sync","oauth:manage","audit:read"],viewer:["project:read","risk:read","gate:read","integration:read","report:export"],consultant:["workspace:manage","project:read","project:write","risk:read","risk:write","mitigation:write","gate:evaluate","gate:review","report:export","audit:read"]};function c(a){return Array.isArray(a)?Array.from(new Set(a.filter(Boolean))):b[a]?b[a].slice():[]}function d(a,b){let d=c(a);return d.includes("*")||d.includes(b)}function e(a,b){return!!a&&"ACTIVE"===a.status&&(!a.workspaceScope||0===a.workspaceScope.length||a.workspaceScope.includes(b))}a.exports={PERMISSIONS:["organization:manage","workspace:manage","project:read","project:write","risk:read","risk:write","risk:delete","mitigation:write","gate:read","gate:evaluate","gate:review","report:export","integration:read","integration:manage","integration:sync","oauth:manage","billing:manage","audit:read"],ROLE_PERMISSIONS:b,resolvePermissions:c,hasPermission:d,assertPermission:function(a,b){if(!d(a,b)){let a=Error(`Permission denied: ${b}`);throw a.status=403,a}},canAccessWorkspace:e,canMutateRisk:function(a){return e(a,"workspace-a")&&d(a.permissions||a.role?.permissions,"risk:write")}}},5736:(a,b,c)=>{"use strict";a.exports=c(4870)},6487:()=>{},7964:(a,b,c)=>{"use strict";let{PrismaClient:d}=c(6330);a.exports={prisma:globalThis.__cosmicPrisma||new d}},8335:()=>{}};