| name | root-cause-analyzer |
| description | Systematic root cause analysis skill with multiple investigation methodologies. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"quality-engineering","backlog-id":"SK-IE-019"} |
| graph | {"domains":["domain:industrial-engineering"],"skillAreas":["skill-area:statistical-analysis","skill-area:organizational-design","skill-area:data-analysis"],"roles":["role:operations-analyst","role:research-engineer"]} |
root-cause-analyzer
You are root-cause-analyzer - a specialized skill for systematic problem investigation and root cause identification.
Overview
This skill enables AI-powered root cause analysis including:
- Is/Is Not analysis for problem definition
- 5 Whys facilitation and documentation
- Ishikawa (fishbone) diagram generation
- Fault tree analysis (FTA) construction
- Pareto chart generation
- Hypothesis testing for cause verification
- Corrective action development
- Effectiveness verification planning
Capabilities
1. Is/Is Not Problem Definition
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class IsIsNotAnalysis:
"""
Structured problem definition using Is/Is Not
"""
what_is: str
what_is_not: str
where_is: str
where_is_not: str
when_is: str
when_is_not: str
extent_is: str
extent_is_not: str
distinctions: List[str] = None
changes: List[str] = None
def generate_problem_statement(self):
return f"""
PROBLEM STATEMENT:
{self.what_is} is occurring at {self.where_is}.
The problem was first observed {self.when_is}.
The extent is: {self.extent_is}.
DISTINCTIONS:
This occurs at {self.where_is} but NOT at {self.where_is_not}.
This happens {self.when_is} but NOT {self.when_is_not}.
KEY DISTINCTIONS: {', '.join(self.distinctions or [])}
RECENT CHANGES: {', '.join(self.changes or [])}
"""
2. 5 Whys Analysis
@dataclass
class WhyStep:
level: int
question: str
answer: str
evidence: str = ""
verified: bool = False
class FiveWhysAnalysis:
"""
5 Whys root cause analysis
"""
def __init__(self, problem_statement: str):
self.problem_statement = problem_statement
self.why_chain: List[WhyStep] = []
def add_why(self, answer: str, evidence: str = ""):
level = len(self.why_chain) + 1
if level == 1:
question = f"Why did {self.problem_statement} occur?"
else:
prev_answer = self.why_chain[-1].answer
question = f"Why did {prev_answer}?"
self.why_chain.append(WhyStep(
level=level,
question=question,
answer=answer,
evidence=evidence
))
def get_root_cause(self):
if self.why_chain:
return self.why_chain[-].answer
():
(.why_chain) < :
{: , : }
i ((.why_chain) - , , -):
cause = .why_chain[i].answer
effect = .why_chain[i-].answer
{
: ,
: .get_root_cause(),
: (.why_chain)
}
():
{
: .problem_statement,
: [
{
: w.level,
: w.question,
: w.answer,
: w.evidence,
: w.verified
}
w .why_chain
],
: .get_root_cause()
}
3. Ishikawa (Fishbone) Diagram
class IshikawaDiagram:
"""
Cause and Effect (Fishbone) Diagram
"""
MANUFACTURING_6M = [
"Manpower", "Method", "Machine",
"Material", "Measurement", "Mother Nature (Environment)"
]
SERVICE_CATEGORIES = [
"People", "Process", "Policy",
"Place", "Procedure", "Product"
]
def __init__(self, effect: str, categories: List[str] = None):
self.effect = effect
self.categories = categories or self.MANUFACTURING_6M
self.causes = {cat: [] for cat in self.categories}
def add_cause(self, category: str, cause: str, sub_causes: List[str] = None):
if category in self.causes:
self.causes[category].append({
"cause": cause,
"sub_causes": sub_causes or []
})
():
lines = []
lines.append()
lines.append( * )
category .categories:
lines.append()
cause_item .causes[category]:
lines.append()
sub cause_item[]:
lines.append()
.join(lines)
():
{
: .effect,
: .categories,
: .causes
}
():
all_causes = []
category, causes .causes.items():
cause_item causes:
cause = cause_item[]
score = team_rankings.get(cause, )
all_causes.append({
: category,
: cause,
: score
})
(all_causes, key= x: x[], reverse=)
4. Fault Tree Analysis
from enum import Enum
class GateType(Enum):
AND = "AND"
OR = "OR"
@dataclass
class FaultTreeNode:
event: str
gate: Optional[GateType] = None
probability: Optional[float] = None
children: List['FaultTreeNode'] = None
def calculate_probability(self):
"""
Calculate top event probability
"""
if not self.children:
return self.probability or 0
child_probs = [c.calculate_probability() for c in self.children]
if self.gate == GateType.AND:
result = 1
for p in child_probs:
result *= p
return result
elif self.gate == GateType.OR:
result = 1
p child_probs:
result *= ( - p)
- result
:
():
.root = FaultTreeNode(event=top_event)
():
parent = ._find_node(.root, parent_event)
parent:
parent.gate = gate_type
parent.children = [FaultTreeNode(event=e) e child_events]
():
node = ._find_node(.root, event)
node:
node.probability = probability
() -> [FaultTreeNode]:
node.event == event:
node
node.children:
child node.children:
found = ._find_node(child, event)
found:
found
():
.root.calculate_probability()
():
cut_sets = []
._find_cut_sets(.root, [], cut_sets)
cut_sets
():
node.children:
all_sets.append(current_set + [node.event])
node.gate == GateType.OR:
child node.children:
._find_cut_sets(child, current_set, all_sets)
node.gate == GateType.AND:
combined = current_set
child node.children:
child.children:
combined.append(child.event)
all_sets.append(combined)
5. Pareto Analysis
import numpy as np
def pareto_analysis(data: dict, cumulative_threshold: float = 80):
"""
Pareto analysis to identify vital few
data: {category: count}
"""
sorted_data = sorted(data.items(), key=lambda x: x[1], reverse=True)
total = sum(data.values())
cumulative = 0
cumulative_pct = 0
results = []
vital_few = []
for category, count in sorted_data:
pct = count / total * 100
cumulative += count
cumulative_pct = cumulative / total * 100
entry = {
"category": category,
"count": count,
"percent": round(pct, 1),
"cumulative_count": cumulative,
"cumulative_percent": round(cumulative_pct, 1)
}
results.append(entry)
if cumulative_pct <= cumulative_threshold:
vital_few.append(category)
return {
"data": results,
"vital_few": vital_few,
"vital_few_count": len(vital_few),
"vital_few_percent": round(sum(data[c] for c in vital_few) / total * 100, 1),
: (data) - (vital_few),
: cumulative_threshold
}
6. Corrective Action Planning
@dataclass
class CorrectiveAction:
root_cause: str
action_type: str
description: str
responsible: str
target_date: str
verification_method: str
status: str = "Open"
effectiveness: Optional[str] = None
def develop_corrective_actions(root_causes: List[str]):
"""
Guide development of corrective actions for root causes
"""
action_plan = {
"containment_actions": [],
"corrective_actions": [],
"preventive_actions": []
}
for rc in root_causes:
action_plan["containment_actions"].append({
"root_cause": rc,
"prompt": f"What immediate action can contain the effect of '{rc}'?",
"examples": ["100% inspection", "Quarantine suspect product", "Sort and rework"]
})
action_plan["corrective_actions"].append({
"root_cause": rc,
"prompt": f"What action will eliminate '{rc}' from occurring?",
"examples": [, , ]
})
action_plan[].append({
: rc,
: ,
: [, , ]
})
action_plan
Process Integration
This skill integrates with the following processes:
root-cause-analysis-investigation.js
failure-mode-effects-analysis.js
kaizen-event-facilitation.js
Output Format
{
"problem_statement": "Defective welds on assembly line 3",
"is_is_not": {
"what_is": "Incomplete weld penetration",
"where_is": "Station 3B only",
"when_is": "Since January 15"
},
"five_whys": {
"root_cause": "Worn electrode tips not replaced per schedule",
"chain_length": 5
},
"pareto": {
"vital_few": ["Electrode condition", "Gas flow"],
"vital_few_percent": 78
},
"corrective_actions": [
{
"action": "Implement electrode tip change schedule"
Best Practices
- Define problem clearly - Use Is/Is Not
- Go to gemba - Observe the actual problem
- Use data - Don't guess at causes
- Verify each why - Evidence-based chain
- Address true root cause - Not symptoms
- Verify effectiveness - Measure improvement
Constraints
- Document all evidence
- Include cross-functional team
- Verify containment effectiveness
- Track action completion