/home/techb158/cosmic.abdallabala.com/public
Edit: /home/techb158/cosmic.abdallabala.com/public/risk-engine.js (10582B)
(function (root, factory) {
if (typeof module === "object" && module.exports) {
module.exports = factory();
} else {
root.CosmicRiskEngine = factory();
}
})(typeof self !== "undefined" ? self : this, function () {
"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 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, 0, 100);
const mitigationEffectiveness = clamp(risk.mitigationEffectiveness, 0, 100);
const rawScore = probability * impact * detectability;
const normalizedScore = Math.round((rawScore / 125) * 100);
const reduction = (mitigationProgress / 100) * (mitigationEffectiveness / 100);
const residualScore = risk.status === "Closed"
? Math.round(normalizedScore * 0.1)
: Math.round(normalizedScore * (1 - reduction));
return Object.assign({}, risk, {
rawScore,
normalizedScore,
residualScore: clamp(residualScore, 0, 100),
severity: getLevel(normalizedScore),
residualSeverity: getLevel(residualScore)
});
}
function getLevel(score) {
const s = clamp(score, 0, 100);
const level = LEVELS.find(item => s >= item.min && s <= item.max);
return level ? level.name : "Unknown";
}
function average(values) {
if (!values.length) return 0;
return Math.round(values.reduce((sum, value) => sum + value, 0) / values.length);
}
function dimensionScores(scoredRisks) {
const result = {};
DIMENSIONS.forEach(dimension => {
const risks = scoredRisks.filter(r => r.dimension === dimension && r.status !== "Closed");
result[dimension] = average(risks.map(r => r.residualScore));
});
return result;
}
function lifecycleScores(data, scoredRisks) {
return (data.lifecycle || []).map(phase => {
const phaseRisks = scoredRisks.filter(r => r.lifecyclePhase === phase.name && r.status !== "Closed");
const riskScore = average(phaseRisks.map(r => r.residualScore));
return Object.assign({}, phase, {
openRisks: phaseRisks.length,
riskScore,
riskLevel: getLevel(riskScore)
});
});
}
function selectedExperiment(data) {
return (data.experiments || []).find(e => e.selected) || (data.experiments || [])[0] || null;
}
function mitigationCompletion(scoredRisks) {
const active = scoredRisks.filter(r => r.status !== "Closed");
return average(active.map(r => clamp(r.mitigationProgress, 0, 100)));
}
function calculateOverallScore(scoredRisks) {
const active = scoredRisks.filter(r => r.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(r => r.normalizedScore));
const avgTopResidual = average(topRisks.map(r => r.residualScore));
const criticalOpen = active.filter(r => r.normalizedScore >= 75 && !["Accepted", "Approved"].includes(r.approvalStatus)).length;
const highUnapproved = active.filter(r => r.normalizedScore >= 50 && !["Accepted", "Approved"].includes(r.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 evaluateGate(data, scoredRisks, overallScore, mitigationPct) {
const thresholds = data.thresholds || {};
const reviews = data.reviews || {};
const selected = selectedExperiment(data);
const active = scoredRisks.filter(r => r.status !== "Closed");
const criticalOpen = active.filter(r => r.normalizedScore >= 75 && !["Accepted", "Approved"].includes(r.approvalStatus)).length;
const unapprovedHigh = active.filter(r => r.normalizedScore >= 50 && !["Accepted", "Approved"].includes(r.approvalStatus)).length;
const criteria = [
{
id: "G-001",
name: "Overall risk score",
required: `<= ${thresholds.overallRiskMax ?? 50}`,
actual: overallScore,
status: overallScore <= (thresholds.overallRiskMax ?? 50) ? "Pass" : "Blocked",
evidence: "Calculated from residual active risks and approval penalty."
},
{
id: "G-002",
name: "Open critical risks",
required: `<= ${thresholds.criticalOpenMax ?? 0}`,
actual: criticalOpen,
status: criticalOpen <= (thresholds.criticalOpenMax ?? 0) ? "Pass" : "Blocked",
evidence: "Critical risks must be closed, accepted, or approved."
},
{
id: "G-003",
name: "Mitigation completeness",
required: `>= ${thresholds.mitigationCompletionMin ?? 60}%`,
actual: `${mitigationPct}%`,
status: mitigationPct >= (thresholds.mitigationCompletionMin ?? 60) ? "Pass" : "Blocked",
evidence: "Average mitigation progress across active risks."
},
{
id: "G-004",
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",
evidence: reviews.dataReadiness ? reviews.dataReadiness.evidence : "Data readiness review missing."
},
{
id: "G-005",
name: "Selected model performance",
required: `F1 >= ${thresholds.selectedModelF1Min ?? 0.8}`,
actual: selected ? selected.f1 : "Missing",
status: selected && selected.f1 >= (thresholds.selectedModelF1Min ?? 0.8) ? "Pass" : "Blocked",
evidence: selected ? `${selected.name} selected for gate review.` : "No selected experiment."
},
{
id: "G-006",
name: "Selected model stability",
required: `>= ${thresholds.selectedModelStabilityMin ?? 75}`,
actual: selected ? selected.stability : "Missing",
status: selected && selected.stability >= (thresholds.selectedModelStabilityMin ?? 75) ? "Pass" : "Warning",
evidence: selected ? "Stability is based on repeated evaluation variation." : "No selected experiment."
},
{
id: "G-007",
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",
evidence: reviews.ethicalReview ? reviews.ethicalReview.evidence : "Ethical review missing."
},
{
id: "G-008",
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",
evidence: reviews.legalReview ? reviews.legalReview.evidence : "Legal review missing."
},
{
id: "G-009",
name: "High-risk approval state",
required: "No unapproved high risks",
actual: unapprovedHigh,
status: unapprovedHigh === 0 ? "Pass" : "Blocked",
evidence: "High risks require owner approval, acceptance, closure, or documented treatment."
}
];
const blocked = criteria.filter(c => c.status === "Blocked");
const warnings = criteria.filter(c => c.status === "Warning");
let status = "Ready";
if (blocked.length) status = "Blocked";
else if (warnings.length || overallScore >= (thresholds.gateWarningScore ?? 35)) status = "Warning";
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(data) {
const scoredRisks = (data.risks || []).map(scoreRisk);
const mitigationPct = mitigationCompletion(scoredRisks);
const overallScore = calculateOverallScore(scoredRisks);
const dimensions = dimensionScores(scoredRisks);
const lifecycle = lifecycleScores(data, scoredRisks);
const gate = evaluateGate(data, scoredRisks, overallScore, mitigationPct);
const active = scoredRisks.filter(r => r.status !== "Closed");
const topRisks = active.slice().sort((a, b) => b.residualScore - a.residualScore).slice(0, 8);
const criticalRisks = active.filter(r => r.normalizedScore >= 75).length;
const highRisks = active.filter(r => r.normalizedScore >= 50 && r.normalizedScore < 75).length;
const mitigations = (data.mitigations || []).map(mitigation => {
const risk = scoredRisks.find(item => item.id === mitigation.riskId);
return Object.assign({}, mitigation, {
riskResidualScore: risk ? risk.residualScore : null,
riskNormalizedScore: risk ? risk.normalizedScore : null,
riskResidualSeverity: risk ? risk.residualSeverity : "Unknown",
riskStatus: risk ? risk.status : "Unknown",
riskApprovalStatus: risk ? risk.approvalStatus : "Unknown"
});
});
return {
project: data.project,
summary: {
overallScore,
riskLevel: getLevel(overallScore),
gateStatus: gate.status,
openRisks: active.length,
totalRisks: scoredRisks.length,
highRisks,
criticalRisks,
mitigationCompletion: mitigationPct,
assessmentDate: data.project.assessmentDate
},
dimensions,
lifecycle,
gate,
scoredRisks,
topRisks,
mitigations,
indicators: data.indicators || [],
experiments: data.experiments || [],
reviews: data.reviews || {},
thresholds: data.thresholds || {}
};
}
return {
scoreRisk,
getLevel,
calculateDashboard,
evaluateGate
};
});