/home/techb158/cosmic-risk.abdallabala.com/src/domain
NameSizeModeActions
entitlements.js26980644editdlrm
integrations.js44380644editdlrm
permissions.js37300644editdlrm
risk-engine.js134520644editdlrm
Edit: /home/techb158/cosmic-risk.abdallabala.com/src/domain/risk-engine.js (13452B)
const DIMENSIONS = ["Organizational", "Technical", "Human", "Governance", "Legal", "Ethical", "Operational"]; 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"); const lifecyclePhases = project.lifecyclePhases || []; const lifecycleReadiness = lifecycleScores(lifecyclePhases, risks).map((phase, i) => ({ ...phase, readinessScore: Math.max(0, 100 - phase.riskScore), code: `LC-${String(i + 1).padStart(2, '0')}` })); const presentDims = [...new Set(risks.map(r => r.dimension).filter(Boolean))]; const DIM_ORDER = ["Organizational", "Technical", "Human", "Governance", "Ethical", "Legal", "Operational"]; const ordered = presentDims.length > 0 ? DIM_ORDER.filter(d => presentDims.includes(d)) : DIMENSIONS; const dimensionResidual = ordered.map(dim => { const dimRisks = risks.filter(r => r.dimension === dim); return { name: dim, score: average(dimRisks.map(r => r.residualScore)), openRisks: active.filter(r => r.dimension === dim).length, totalRisks: dimRisks.length }; }); const orgScore = dimensionResidual.find(d => d.name === "Organizational")?.score || 0; const techScore = dimensionResidual.find(d => d.name === "Technical")?.score || 0; const humanScore = dimensionResidual.find(d => d.name === "Human")?.score || 0; return { project: { id: project.id, workspaceId: project.workspaceId, name: project.name, subtitle: project.subtitle, status: project.status, assessmentDate: project.assessmentDate, projectType: project.projectType, currentLifecyclePhase: project.currentLifecyclePhase }, 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), dimensionResidual, governanceTriangle: { organizational: orgScore, technical: techScore, human: humanScore }, lifecycle: lifecycleScores(lifecyclePhases, risks), lifecycleReadiness, 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 || [], workspace: project.workspace ? { id: project.workspace.id, name: project.workspace.name, organizationId: project.workspace.organizationId } : null, integrations: project.workspace?.integrations || [] }; } module.exports = { DIMENSIONS, scoreRisk, getLevel, calculateDashboard, evaluateGate, calculateOverallScore, scoreProjectRisks };