| name | risk-assessment |
| description | Risk identification and quantification using FMEA, risk matrices, and FAIR methodology for project and technical risks |
| allowed-tools | Read, Glob, Grep, Write, Edit |
Risk Assessment Skill
When to Use This Skill
Use this skill when:
- Risk Assessment tasks - Working on risk identification and quantification using fmea, risk matrices, and fair methodology for project and technical risks
- Planning or design - Need guidance on Risk Assessment approaches
- Best practices - Want to follow established patterns and standards
Overview
Risk identification, analysis, and quantification using industry-standard methodologies including FMEA, risk matrices, and FAIR for project, technical, and security risks.
MANDATORY: Documentation-First Approach
Before providing risk assessment guidance:
- Invoke
docs-managementskill to access official methodology documentation - Verify framework currency via MCP servers (perplexity for FAIR updates, NIST guidelines)
- Base all guidance on authoritative sources - cite frameworks and standards
Risk Matrix Approach
Standard 5x5 Risk Matrix
Impact → Negligible Minor Moderate Major Catastrophic
Probability ↓ (1) (2) (3) (4) (5)
─────────────────────────────────────────────────────────────────────
Almost Certain(5) 5 10 15 20 25
Likely (4) 4 8 12 16 20
Possible (3) 3 6 9 12 15
Unlikely (2) 2 4 6 8 10
Rare (1) 1 2 3 4 5
Risk Score Interpretation
public enum RiskLevel
{
Low, // Score 1-4: Accept with monitoring
Medium, // Score 5-9: Mitigation recommended
High, // Score 10-16: Mitigation required
Critical // Score 17-25: Immediate action required
}
public sealed record RiskScore(
int Probability,
int Impact,
int Score,
RiskLevel Level)
{
public static RiskScore Calculate(int probability, int impact)
{
var score = probability * impact;
var level = score switch
{
<= 4 => RiskLevel.Low,
<= 9 => RiskLevel.Medium,
<= 16 => RiskLevel.High,
_ => RiskLevel.Critical
};
return new RiskScore(probability, impact, score, level);
}
}
Risk Categories for Software Projects
public enum RiskCategory
{
// Technical Risks
TechnicalComplexity,
TechnologyMaturity,
IntegrationRisk,
PerformanceRisk,
SecurityRisk,
DataQualityRisk,
// Schedule Risks
DependencyRisk,
ResourceAvailability,
ScopeCreep,
RequirementsVolatility,
// Organizational Risks
StakeholderAlignment,
SkillsGap,
VendorDependency,
RegulatoryCompliance,
// External Risks
MarketChanges,
CompetitorActions,
EconomicFactors,
TechnologyObsolescence
}
public sealed record ProjectRisk(
string Id,
string Title,
string Description,
RiskCategory Category,
RiskScore InherentRisk,
IReadOnlyList<Mitigation> Mitigations,
RiskScore ResidualRisk,
string Owner,
DateOnly IdentifiedDate,
DateOnly? ReviewDate,
RiskStatus Status);
public enum RiskStatus
{
Identified,
Analyzing,
Mitigating,
Monitoring,
Closed,
Accepted
}
FMEA (Failure Mode and Effects Analysis)
FMEA Structure
public sealed record FailureMode(
string Id,
string Component,
string Function,
string PotentialFailure,
string PotentialEffect,
int Severity, // 1-10: Impact of failure
string PotentialCause,
int Occurrence, // 1-10: Likelihood of occurrence
string CurrentControls,
int Detection, // 1-10: Ability to detect (10 = undetectable)
int RPN) // Risk Priority Number = S × O × D
{
public static int CalculateRPN(int severity, int occurrence, int detection)
=> severity * occurrence * detection;
}
public sealed class FMEAAnalyzer
{
public FMEAResult Analyze(IEnumerable<FailureMode> failureModes)
{
var sorted = failureModes
.OrderByDescending(fm => fm.RPN)
.ToList();
return new FMEAResult(
FailureModes: sorted,
HighPriorityCount: sorted.Count(fm => fm.RPN >= 200),
MediumPriorityCount: sorted.Count(fm => fm.RPN is >= 100 and < 200),
RecommendedActions: GenerateActions(sorted));
}
private IReadOnlyList<RecommendedAction> GenerateActions(
IReadOnlyList<FailureMode> sorted)
{
var actions = new List<RecommendedAction>();
foreach (var fm in sorted.Where(fm => fm.RPN >= 100))
{
// Prioritize based on highest contributing factor
if (fm.Severity >= 8)
actions.Add(new RecommendedAction(
fm.Id,
ActionType.DesignChange,
$"Reduce severity for {fm.Component}: {fm.PotentialFailure}"));
else if (fm.Occurrence >= 6)
actions.Add(new RecommendedAction(
fm.Id,
ActionType.PreventiveControl,
$"Reduce occurrence for {fm.Component}: {fm.PotentialCause}"));
else if (fm.Detection >= 6)
actions.Add(new RecommendedAction(
fm.Id,
ActionType.DetectionImprovement,
$"Improve detection for {fm.Component}: add monitoring/tests"));
}
return actions;
}
}
FMEA Severity Scale (Software)
| Rating | Description | Criteria |
|---|---|---|
| 10 | Catastrophic | Complete system failure, data loss, safety hazard |
| 9 | Critical | System unusable, major functionality lost |
| 8 | Severe | Significant degradation, workaround required |
| 7 | Major | Important feature unavailable, user impact high |
| 6 | Moderate | Feature partially available, moderate user impact |
| 5 | Low | Minor feature impact, workaround available |
| 4 | Minor | Cosmetic issue, no functional impact |
| 3 | Very Minor | Rarely noticed by users |
| 2 | Negligible | Internal issue only |
| 1 | None | No discernible effect |
FMEA for Software Components Example
public static class SoftwareFMEATemplates
{
public static IEnumerable<FailureMode> DatabaseComponentFMEA()
{
yield return new FailureMode(
Id: "DB-001",
Component: "Database Connection Pool",
Function: "Manage database connections",
PotentialFailure: "Connection pool exhaustion",
PotentialEffect: "API requests timeout, service unavailable",
Severity: 8,
PotentialCause: "Connection leaks, high concurrent load",
Occurrence: 4,
CurrentControls: "Connection timeout, pool size monitoring",
Detection: 3,
RPN: FailureMode.CalculateRPN(8, 4, 3)); // 96 - Medium
yield return new FailureMode(
Id: "DB-002",
Component: "Database",
Function: "Store and retrieve data",
PotentialFailure: "Data corruption",
PotentialEffect: "Incorrect data returned, business logic failures",
Severity: 10,
PotentialCause: "Concurrent write conflicts, incomplete transactions",
Occurrence: 2,
CurrentControls: "Transaction isolation, checksums",
Detection: 5,
RPN: FailureMode.CalculateRPN(10, 2, 5)); // 100 - High priority
}
}
FAIR (Factor Analysis of Information Risk)
FAIR Model Structure
public sealed record FAIRAnalysis(
string ScenarioName,
ThreatEventFrequency TEF,
Vulnerability Vuln,
LossEventFrequency LEF,
LossMagnitude LM,
RiskQuantification Risk);
public sealed record ThreatEventFrequency(
double ContactFrequency, // Times threat contacts asset per year
double ProbabilityOfAction, // Probability threat acts on contact
double AnnualTEF) // = ContactFrequency × ProbabilityOfAction
{
public static ThreatEventFrequency Calculate(
double contactFrequency,
double probabilityOfAction)
{
return new ThreatEventFrequency(
contactFrequency,
probabilityOfAction,
contactFrequency * probabilityOfAction);
}
}
public sealed record Vulnerability(
double ThreatCapability, // 0-1: Attacker skill/resources
double ControlStrength, // 0-1: Effectiveness of defenses
double VulnerabilityLevel) // Probability attack succeeds
{
public static Vulnerability Calculate(
double threatCapability,
double controlStrength)
{
// Vulnerability = max(0, ThreatCapability - ControlStrength)
var vuln = Math.Max(0, threatCapability - controlStrength);
return new Vulnerability(threatCapability, controlStrength, vuln);
}
}
public sealed record LossEventFrequency(
double TEF,
double Vulnerability,
double AnnualLEF) // = TEF × Vulnerability
{
public static LossEventFrequency Calculate(
ThreatEventFrequency tef,
Vulnerability vuln)
{
return new LossEventFrequency(
tef.AnnualTEF,
vuln.VulnerabilityLevel,
tef.AnnualTEF * vuln.VulnerabilityLevel);
}
}
FAIR Loss Magnitude Categories
public sealed record LossMagnitude(
MonetaryRange PrimaryLoss,
MonetaryRange SecondaryLoss,
MonetaryRange TotalLoss);
public sealed record MonetaryRange(
decimal Minimum,
decimal MostLikely,
decimal Maximum,
decimal Expected) // PERT: (Min + 4×ML + Max) / 6
{
public static MonetaryRange Calculate(decimal min, decimal mostLikely, decimal max)
{
var expected = (min + 4 * mostLikely + max) / 6;
return new MonetaryRange(min, mostLikely, max, expected);
}
}
public enum LossType
{
// Primary Losses (direct)
ProductivityLoss,
ResponseCost,
ReplacementCost,
// Secondary Losses (indirect)
ReputationDamage,
RegulatoryFines,
LegalLiability,
CompetitiveDisadvantage
}
public sealed class FAIRCalculator
{
public RiskQuantification QuantifyRisk(
LossEventFrequency lef,
LossMagnitude lm)
{
// Annual Loss Expectancy = LEF × Expected Loss
var ale = (decimal)lef.AnnualLEF * lm.TotalLoss.Expected;
// Monte Carlo for distribution
var simResults = RunSimulation(lef, lm, iterations: 10_000);
return new RiskQuantification(
AnnualLossExpectancy: ale,
Percentile10: simResults.Percentile(10),
Percentile50: simResults.Percentile(50),
Percentile90: simResults.Percentile(90),
MaximumExposure: lm.TotalLoss.Maximum);
}
}
FAIR Analysis Example
public static class FAIRExamples
{
public static FAIRAnalysis DataBreachScenario()
{
// Scenario: External attacker targeting customer database
var tef = ThreatEventFrequency.Calculate(
contactFrequency: 100, // 100 attack attempts/year
probabilityOfAction: 0.5); // 50% are serious attempts
// TEF = 50 threat events/year
var vuln = Vulnerability.Calculate(
threatCapability: 0.7, // Skilled attackers
controlStrength: 0.6); // Reasonable defenses
// Vulnerability = 0.1 (10% success rate)
var lef = LossEventFrequency.Calculate(tef, vuln);
// LEF = 50 × 0.1 = 5 loss events/year
var primaryLoss = MonetaryRange.Calculate(
min: 50_000m,
mostLikely: 200_000m,
max: 1_000_000m);
var secondaryLoss = MonetaryRange.Calculate(
min: 100_000m,
mostLikely: 500_000m,
max: 5_000_000m);
var totalLoss = new LossMagnitude(
PrimaryLoss: primaryLoss,
SecondaryLoss: secondaryLoss,
TotalLoss: MonetaryRange.Calculate(
150_000m, 700_000m, 6_000_000m));
// Annual Loss Expectancy ≈ 5 × $700K = $3.5M
return new FAIRAnalysis(
ScenarioName: "Customer Database Breach",
TEF: tef,
Vuln: vuln,
LEF: lef,
LM: totalLoss,
Risk: new FAIRCalculator().QuantifyRisk(lef, totalLoss));
}
}
Risk Register Template
Risk Register Structure
public sealed class RiskRegister
{
private readonly List<ProjectRisk> _risks = new();
public string ProjectName { get; init; } = "";
public DateOnly CreatedDate { get; init; }
public DateOnly LastReviewDate { get; set; }
public IReadOnlyList<ProjectRisk> Risks => _risks;
public RiskRegisterSummary GetSummary()
{
return new RiskRegisterSummary(
TotalRisks: _risks.Count,
CriticalRisks: _risks.Count(r => r.ResidualRisk.Level == RiskLevel.Critical),
HighRisks: _risks.Count(r => r.ResidualRisk.Level == RiskLevel.High),
MediumRisks: _risks.Count(r => r.ResidualRisk.Level == RiskLevel.Medium),
LowRisks: _risks.Count(r => r.ResidualRisk.Level == RiskLevel.Low),
OpenRisks: _risks.Count(r => r.Status != RiskStatus.Closed),
OverdueReviews: _risks.Count(r =>
r.ReviewDate.HasValue && r.ReviewDate < DateOnly.FromDateTime(DateTime.UtcNow)),
RisksByCategory: _risks
.GroupBy(r => r.Category)
.ToDictionary(g => g.Key, g => g.Count()));
}
public void AddRisk(ProjectRisk risk) => _risks.Add(risk);
public IEnumerable<ProjectRisk> GetTopRisks(int count = 10)
=> _risks
.Where(r => r.Status != RiskStatus.Closed)
.OrderByDescending(r => r.ResidualRisk.Score)
.Take(count);
}
public sealed record Mitigation(
string Id,
string Description,
MitigationType Type,
string Owner,
DateOnly DueDate,
MitigationStatus Status,
decimal EstimatedCost,
int ExpectedRiskReduction); // Percentage reduction
public enum MitigationType
{
Avoid, // Eliminate the risk entirely
Transfer, // Transfer to third party (insurance, contract)
Mitigate, // Reduce probability or impact
Accept // Acknowledge and monitor
}
Risk Identification Techniques
Technique Selection Guide
| Technique | Best For | Participants |
|---|---|---|
| Brainstorming | Initial risk identification | Cross-functional team |
| Checklist Review | Known risk categories | PM, Tech Lead |
| SWOT Analysis | Strategic/business risks | Stakeholders |
| Root Cause Analysis | Post-incident learning | Technical team |
| Expert Interviews | Domain-specific risks | SMEs |
| Assumption Analysis | Requirements risks | BA, PM |
| Delphi Technique | Consensus building | Anonymous experts |
Risk Identification Prompts by Category
public static class RiskIdentificationPrompts
{
public static IEnumerable<string> TechnicalRiskPrompts()
{
yield return "What happens if the chosen technology doesn't scale?";
yield return "What third-party dependencies could become unavailable?";
yield return "What integration points have the most uncertainty?";
yield return "Where is the system most vulnerable to performance issues?";
yield return "What security threats are most likely?";
yield return "What happens if key technical assumptions are wrong?";
}
public static IEnumerable<string> ScheduleRiskPrompts()
{
yield return "What dependencies could delay the project?";
yield return "Which team members are single points of failure?";
yield return "What scope changes are likely to be requested?";
yield return "What requirements are still unclear or volatile?";
yield return "What external deliverables are we waiting on?";
}
public static IEnumerable<string> OrganizationalRiskPrompts()
{
yield return "Which stakeholders might resist the change?";
yield return "What skills gaps exist on the team?";
yield return "What vendor relationships are critical?";
yield return "What regulatory requirements might change?";
yield return "How might organizational priorities shift?";
}
}
Risk Response Strategies
Response Strategy Selection
public static class RiskResponseSelection
{
public static MitigationType RecommendStrategy(ProjectRisk risk)
{
// Critical risks with high impact: try to avoid
if (risk.InherentRisk.Level == RiskLevel.Critical &&
risk.InherentRisk.Impact >= 4)
return MitigationType.Avoid;
// Financial risks: consider transfer
if (risk.Category is RiskCategory.VendorDependency
or RiskCategory.SecurityRisk)
return MitigationType.Transfer;
// Technical risks: usually mitigate
if (risk.Category is RiskCategory.TechnicalComplexity
or RiskCategory.IntegrationRisk
or RiskCategory.PerformanceRisk)
return MitigationType.Mitigate;
// Low probability/impact: accept
if (risk.InherentRisk.Score <= 6)
return MitigationType.Accept;
return MitigationType.Mitigate;
}
}
Workflow
When conducting risk assessment:
- Define Scope: Identify what is being assessed (project, system, component)
- Select Methodology: Choose appropriate framework (Matrix, FMEA, FAIR)
- Identify Risks: Use brainstorming, checklists, expert input
- Analyze Risks: Assess probability and impact
- Prioritize: Rank by risk score or RPN
- Plan Responses: Define mitigation strategies
- Document: Create/update risk register
- Monitor: Establish review cadence
References
For detailed framework documentation:
Last Updated: 2025-12-26