技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
incident-response【数据与研究】Orchestrates production incident response including severity classification, on-call escalation procedures, blameless postmortem analysis, and root cause remediation to minimize downtime and prevent recurrence.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
name: incident-response description: Orchestrates production incident response including severity classification, on-call escalation procedures, blameless postmortem analysis, and root cause remediation to minimize downtime and prevent recurrence. license: MIT compatibility: opencode metadata: version: "1.0.0" domain: coding triggers: incident response, production outage, on-call procedures, postmortem, blameless postmortem, RCA root cause analysis, service degradation, how do i handle a production incident blameless postmortem archetypes:
Orchestrates production incident response including severity classification, on-call escalation procedures, blameless postmortem analysis, and root cause remediation. When loaded, this skill makes the model act as an incident commander — following structured escalation paths, isolating failures to restore service first, then conducting thorough post-incident analysis that focuses on system design flaws rather than individual errors. This skill applies the 5 Laws of Elegant Defense: validate inputs at every boundary (Law 2), fail fast with descriptive error messages including context (Law 4), return new data structures for clean state transitions during incident recovery (Law 3), guide data naturally through failure scenarios (Law 1), and ensure graceful degradation prevents cascading failures (Law 5).
Use this skill when:
Avoid this skill for:
systematic-debugging for local development problemssecurity-review for prevention guidance and contact security team first)Detect and Classify Severity — Assess the incident using the SLA-based severity matrix:
Activate Incident Command — Designate an incident commander (IC) who takes ownership of coordination. The IC's sole responsibility is managing the incident: they do not fix code or investigate root causes during active response. Other engineers work under the IC's direction to restore service. Establish a dedicated communication channel (Slack/Teams), announce the incident with severity classification, affected systems, and initial impact assessment. Checkpoint: Every active incident must have exactly one named IC communicating from a single channel. Multiple decision-makers create confusion and delay recovery. The IC communicates updates every 15 minutes regardless of progress.
Triage and Isolate the Failure — Identify the failure scope using monitoring dashboards, error logs, and service health checks. Apply the "restore first, diagnose later" principle:
Communicate Progress — Send structured incident updates at regular intervals (minimum every 15 minutes during active response). Each update must contain: severity, current status (investigating/mitigated/resolved), impact summary, actions taken, next steps expected. Provide a public status page update for external-facing incidents. Checkpoint: Every stakeholder (engineering team, product managers, customer support, executive leadership) should receive updates through their preferred channel. Customer-facing teams need simpler summaries; engineering needs technical details.
Restore Service and Verify — Confirm service restoration through multiple verification channels: automated health checks pass, error rate drops below acceptable threshold (<0.1% for SEV-1), p95 latency returns to baseline, key user journeys succeed end-to-end (not just API health endpoints). Checkpoint: Do not declare incident resolved until actual user-facing metrics are normal, not just internal service health. A "healthy" API returning correct data on localhost does not mean users are unimpacted.
Conduct Blameless Postmortem — Within 48 hours of resolution, assemble the response team for a structured post-incident review. The session must follow these rules:
Track Improvement Execution — Every action item from the postmortem must be tracked in the project management system with clear acceptance criteria. Review progress in weekly engineering meetings until completed. Validate fixes through testing and, where applicable, chaos engineering or fault injection to confirm the specific failure mode is now mitigated. Checkpoint: Action items should have a target completion within 2 weeks for SEV-1/SEV-2 incidents. If an action item requires architectural changes exceeding two weeks, split it into phased milestones with interim controls.
Automated severity classification using quantifiable metrics ensures consistent incident handling regardless of who receives the alert.
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import IntEnum
class Severity(IntEnum):
"""SLA-based incident severity levels with response time guarantees."""
SEV_1_CRITICAL = 1 # Complete outage — 5 min response, exec notification
SEV_2_HIGH = 2 # Significant degradation — 15 min response, lead notification
SEV_3_MEDIUM = 3 # Non-critical issue — 1 hour response, team notification
SEV_4_LOW = 4 # Minor bug — next business day, backlog tracking
@dataclass
class IncidentMetrics:
"""Quantifiable metrics used for severity classification."""
error_rate_pct: float # Percentage of requests failing (0.0-100.0)
p95_latency_ms: float # 95th percentile response time in milliseconds
affected_user_percentage: float # Percentage of users impacted (0.0-100.0)
data_loss_risk: bool # True if data corruption or loss is possible
security_breach_suspected: bool # True if unauthorized access detected
service_availability_pct: float # Current availability percentage
def classify(self) -> Severity:
"""Classify incident severity based on quantifiable SLA thresholds.
Classification rules follow the principle that user-impacting
metrics always take precedence over internal health signals.
"""
# SEV-1: Complete outage, data loss, or security breach
if (self.error_rate_pct >= 50.0 or
self.service_availability_pct < 95.0 or
self.data_loss_risk or
self.security_breach_suspected):
return Severity.SEV_1_CRITICAL
# SEV-2: Significant functionality degraded
if (self.error_rate_pct >= 10.0 or
self.affected_user_percentage >= 30.0 or
self.p95_latency_ms > 5000): # 5x normal baseline
return Severity.SEV_2_HIGH
# SEV-3: Non-critical but noticeable degradation
if (self.error_rate_pct >= 1.0 or
self.affected_user_percentage >= 5.0 or
self.p95_latency_ms > 2000): # 2x normal baseline
return Severity.SEV_3_MEDIUM
# SEV-4: Minor issues below thresholds
return Severity.SEV_4_LOW
def create_incident_report(
severity: Severity,
service_name: str,
description: str,
metrics: IncidentMetrics,
detected_at: datetime | None = None
) -> dict:
"""Create a structured incident report for the on-call escalation pipeline.
Args:
severity: Classified severity level from automatic or manual assessment.
service_name: Name of the affected service or system.
description: Human-readable incident description.
metrics: Quantifiable metrics used for classification and tracking.
detected_at: When the incident was first detected (defaults to now).
Returns:
Structured dict ready for incident channel posting and stakeholder notification.
"""
response_sla = {
Severity.SEV_1_CRITICAL: timedelta(minutes=5),
Severity.SEV_2_HIGH: timedelta(minutes=15),
Severity.SEV_3_MEDIUM: timedelta(hours=1),
Severity.SEV_4_LOW: timedelta(days=1),
}
return {
"incident_id": f"INC-{datetime.utcnow().strftime('%Y%m%d')}-{severity.value}",
"severity": severity.name,
"severity_level": int(severity),
"service": service_name,
"description": description,
"metrics": {
"error_rate_pct": metrics.error_rate_pct,
"p95_latency_ms": round(metrics.p95_latency_ms, 1),
"affected_users_pct": metrics.affected_user_percentage,
"availability_pct": metrics.service_availability_pct,
},
"response_sla": str(response_sla[severity]),
"detected_at": detected_at.isoformat() if detected_at else datetime.utcnow().isoformat(),
"status": "active",
}
# Usage example: classify a real incident from monitoring data
if __name__ == "__main__":
metrics = IncidentMetrics(
error_rate_pct=23.5,
p95_latency_ms=4800.0,
affected_user_percentage=35.0,
data_loss_risk=False,
security_breach_suspected=False,
service_availability_pct=76.5,
)
severity = metrics.classify()
report = create_incident_report(
severity=severity,
service_name="payment-gateway",
description="Payment processing intermittent — 23% error rate, users reporting declined transactions",
metrics=metrics,
)
print(f"Incident: {report['incident_id']}")
print(f"Severity: {report['severity']} (SLA: {report['response_sla']})")
print(f"Affected users: {report['metrics']['affected_users_pct']}%")
Maintain a structured timeline of all incident actions for postmortem reconstruction. This ensures no action is lost during the chaos of active response.
import threading
from dataclasses import dataclass, field
from datetime import datetime
from typing import Any
@dataclass
class TimelineEntry:
"""A single entry in the incident timeline."""
timestamp: datetime = field(default_factory=datetime.utcnow)
action: str # Short description of what was done
actor: str # Who performed the action (engineer name or role)
details: dict[str, Any] = field(default_factory=dict)
outcome: str | None = None # Result of the action
def to_dict(self) -> dict:
return {
"time": self.timestamp.isoformat(),
"action": self.action,
"actor": self.actor,
"details": self.details,
"outcome": self.outcome,
}
class IncidentTimeline:
"""Thread-safe timeline tracker for incident response actions.
All active responders should log their actions through a shared timeline
instance to create an accurate postmortem record without relying on
memory or fragmented Slack messages.
"""
def __init__(self, incident_id: str):
self.incident_id = incident_id
self._entries: list[TimelineEntry] = []
self._lock = threading.Lock()
def log(
self,
action: str,
actor: str,
details: dict[str, Any] | None = None,
outcome: str | None = None,
) -> TimelineEntry:
"""Log an incident action to the timeline.
All actions during active response must be logged here — especially
rollback decisions, configuration changes, and service restarts.
These form the foundation of the postmortem investigation.
Args:
action: What was done (e.g., "Rolled back deployment v2.14.3").
actor: Who did it (e.g., "on-call-engineer", "incident-commander").
details: Additional context (e.g., {"reason": "5xx spike", "duration_sec": 12}).
outcome: Result of the action (e.g., "Error rate dropped to 0.5%").
Returns:
The created TimelineEntry for confirmation.
"""
entry = TimelineEntry(
action=action,
actor=actor,
details=details or {},
outcome=outcome,
)
with self._lock:
self._entries.append(entry)
return entry
def get_timeline(self) -> list[dict]:
"""Export the full incident timeline as structured data."""
with self._lock:
return [entry.to_dict() for entry in self._entries]
def summary(self) -> dict:
"""Generate a concise timeline summary for status updates."""
actions = len(self._entries)
actors = set(e.actor for e in self._entries)
first_event = self._entries[0].timestamp if self._entries else None
return {
"incident_id": self.incident_id,
"total_actions": actions,
"participants": list(actors),
"duration_minutes": (
(datetime.utcnow() - first_event).total_seconds() / 60
) if first_event else 0,
}
# Usage: shared timeline accessible to all incident responders
if __name__ == "__main__":
timeline = IncidentTimeline("INC-20260101-1")
timeline.log(
"SEV-1 declared — payment gateway returning 503 errors",
actor="on-call-engineer",
details={"affected_users_pct": 45.0, "error_rate_pct": 98.0},
)
timeline.log("Escalated to incident commander: sarah-eng", actor="on-call-engineer")
timeline.log(
"Rolled back payment-gateway deployment from v2.14.3 to v2.14.2",
actor="sarah-eng",
details={"reason": "5xx spike correlated with deploy timestamp"},
outcome="Error rate dropped from 98% to 2.3% within 30 seconds",
)
print(f"Timeline: {timeline.summary()}")
for entry in timeline.get_timeline():
print(f" [{entry['time']}] {entry['action']} ({entry['actor']})")
Structure a postmortem that focuses on system design flaws rather than individual actions.
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class PostmortemFinding:
"""A finding from incident postmortem analysis."""
category: str # "direct", "root_preventable", "root_detectable", "root_containable"
description: str
impact: str # How this contributed to the incident severity and duration
recommendation: str # Specific improvement action
priority: int = 3 # 1 = critical, 2 = high, 3 = medium, 4 = low
@property
def ticket_title(self) -> str:
return f"[{self.category.upper()}] {self.description[:60]}"
@dataclass
class BlamelessPostmortem:
"""Structured postmortem document following blameless principles.
This format ensures every incident produces actionable improvements
without assigning individual blame, focusing instead on systemic fixes.
"""
incident_id: str
service_name: str
severity: int
timeline: list[dict] # From IncidentTimeline.get_timeline()
direct_cause: str # Immediate technical trigger
root_causes: list[str] = field(default_factory=list)
findings: list[PostmortemFinding] = field(default_factory=list)
resolution_steps: list[str] = field(default_factory=list)
def generate_improvement_tickets(self) -> list[dict]:
"""Convert postmortem findings into actionable improvement tickets.
Each ticket must have a clear owner, priority, and deadline.
Tickets are the primary deliverable of any postmortem process.
Returns:
List of ticket dicts ready for project management system import.
"""
tickets = []
for i, finding in enumerate(self.findings):
tickets.append({
"title": finding.ticket_title,
"category": finding.category,
"description": f"{finding.description}\n\nImpact: {finding.impact}\nRecommendation: {finding.recommendation}",
"priority": finding.priority,
"parent_incident": self.incident_id,
})
return tickets
def generate_summary(self) -> str:
"""Generate a human-readable postmortem summary for stakeholders."""
lines = [
f"## Postmortem: {self.service_name} ({self.incident_id})",
f"Severity: SEV-{self.severity}",
f"Root Causes:\n" + "\n".join(f" - {rc}" for rc in self.root_causes),
"",
"## Action Items",
]
for finding in self.findings:
lines.append(f"- **[{finding.priority}]** {finding.recommendation}")
return "\n".join(lines)
# Usage example: structure findings from a payment gateway incident
if __name__ == "__main__":
pm = BlamelessPostmortem(
incident_id="INC-20260101-1",
service_name="payment-gateway",
severity=1,
timeline=[], # Would be populated from IncidentTimeline
direct_cause="Connection pool exhaustion after database failover increased query latency by 40x",
root_causes=[
"Connection pool size was hardcoded to 20 — insufficient for failover burst traffic",
"No circuit breaker between payment service and database — failures cascaded",
"Health checks passed even while connections were queuing — monitoring gap",
],
findings=[
PostmortemFinding(
category="preventable",
description="Connection pool size hardcoded to 20, insufficient for failover burst",
impact="Pool exhaustion caused all payment requests to queue until timeout (30s)",
recommendation="Make connection pool size configurable and set min/max based on expected failover traffic patterns. Add pool usage metrics alerting at 80% capacity.",
priority=1,
),
PostmortemFinding(
category="preventable",
description="No circuit breaker between payment service and database",
impact="Database slowdown cascaded to complete payment service outage",
recommendation="Implement circuit breaker with configurable failure threshold (5 consecutive failures) and half-open retry after 30 seconds. See coding-microservice-resilience-patterns skill.",
priority=1,
),
PostmortemFinding(
category="detectable",
description="Health check endpoint returned healthy while connections were queuing",
impact="Monitoring did not surface the degradation until error rate alerts fired 8 minutes later",
recommendation="Update health check to verify connection availability by performing a real database query. Alert on queue depth > 10.",
priority=2,
),
],
)
print(pm.generate_summary())
for ticket in pm.generate_improvement_tickets():
print(f"\nTicket: {ticket['title']} (Priority: {ticket['priority']})")
When conducting incident response or postmortem analysis, produce:
| Skill | Purpose |
|---|---|
systematic-debugging | Root cause investigation methodology for individual bugs; use this during postmortem phase to analyze specific failure points |
observability-patterns | Metrics, logging, and tracing setup that enables faster incident detection; preventive skill used before incidents occur |
engineering-principles | Foundational software engineering principles that prevent common failure modes when designing resilient systems |
production-logging | Structured logging practices that provide the signal needed during incident investigation to reconstruct what happened |
Authoritative documentation links for this domain. The model follows markdown links at load time to resolve external references and inline content.