postmortem-writing

Par wshobson · agents

Rédigez des postmortems efficaces sans culture de la faute, avec une analyse des causes racines, des chronologies et des plans d'action. À utiliser lors des bilans d'incident, pour la rédaction de documents postmortem ou pour améliorer les processus de réponse aux incidents.

npx skills add https://github.com/wshobson/agents --skill postmortem-writing

Rédaction de Postmortems

Guide complet pour rédiger des postmortems efficaces et sans culpabilisation qui favorisent l'apprentissage organisationnel et préviennent la récurrence des incidents.

Quand utiliser cette compétence

  • Mener des révisions post-incident
  • Rédiger des documents de postmortem
  • Animer des réunions de postmortem sans culpabilisation
  • Identifier les causes racines et les facteurs contributifs
  • Créer des éléments de suivi exploitables
  • Construire une culture d'apprentissage organisationnel

Concepts fondamentaux

1. Culture sans culpabilisation

Axé sur la culpabilité Sans culpabilisation
« Qui a causé cela ? » « Quelles conditions l'ont permis ? »
« Quelqu'un a commis une erreur » « Le système a permis cette erreur »
Punir les individus Améliorer les systèmes
Cacher les informations Partager les apprentissages
Peur de s'exprimer Sécurité psychologique

2. Déclencheurs de postmortem

  • Incidents SEV1 ou SEV2
  • Pannes orientées clients > 15 minutes
  • Perte de données ou incidents de sécurité
  • Quasi-accidents qui auraient pu être graves
  • Nouveaux modes de défaillance
  • Incidents nécessitant une intervention inhabituelle

Démarrage rapide

Calendrier du postmortem

Jour 0 : Incident survient
Jour 1-2 : Brouillon du document postmortem
Jour 3-5 : Réunion de postmortem
Jour 5-7 : Finalisation du document, création de tickets
Semaine 2+ : Complétude des éléments d'action
Trimestriel : Examen des patterns entre incidents

Modèles

Modèle 1 : Postmortem standard

# Postmortem : [Titre de l'incident]

**Date** : 15-01-2024
**Auteurs** : @alice, @bob
**Statut** : Brouillon | En révision | Final
**Sévérité de l'incident** : SEV2
**Durée de l'incident** : 47 minutes

## Résumé exécutif

Le 15 janvier 2024, le service de traitement des paiements a subi une panne de 47 minutes affectant environ 12 000 clients. La cause racine était un épuisement du pool de connexions à la base de données déclenché par un changement de configuration dans le déploiement v2.3.4. L'incident a été résolu en restauration vers v2.3.3 et en augmentation des limites du pool de connexions.

**Impact** :

- 12 000 clients incapables de finaliser des achats
- Perte de revenus estimée : 45 000 $
- 847 tickets d'assistance créés
- Aucune perte de données ou implication de sécurité

## Chronologie (tous les horaires en UTC)

| Heure | Événement                                          |
| ----- | -------------------------------------------------- |
| 14:23 | Déploiement v2.3.4 complété en production         |
| 14:31 | Première alerte : `payment_error_rate > 5%`       |
| 14:33 | Ingénieur d'astreinte @alice reconnaît l'alerte   |
| 14:35 | Investigation initiale commence, taux d'erreur 23% |
| 14:41 | Incident déclaré SEV2, @bob rejoint              |
| 14:45 | Épuisement des connexions de base de données identifié |
| 14:52 | Décision de restaurer le déploiement              |
| 14:58 | Restauration vers v2.3.3 initiée                 |
| 15:10 | Restauration complète, taux d'erreur en baisse    |
| 15:18 | Service complètement rétabli, incident résolu     |

## Analyse de la cause racine

### Ce qui s'est passé

Le déploiement v2.3.4 contenait un changement au modèle de requête de base de données qui supprimait involontairement le pooling de connexions pour un endpoint fréquemment appelé. Chaque requête ouvrait une nouvelle connexion de base de données au lieu de réutiliser des connexions en pool.

### Pourquoi c'est arrivé

1. **Cause immédiate** : Changement de code dans `PaymentRepository.java` qui remplaçait la `DataSource` en pool par des appels directs à `DriverManager.getConnection()`.

2. **Facteurs contributifs** :
   - La révision de code n'a pas capté le changement de gestion des connexions
   - Aucun test d'intégration spécifique pour le comportement du pool de connexions
   - L'environnement de staging a un trafic plus faible, masquant le problème
   - Le seuil d'alerte des métriques de connexion de base de données était trop élevé (90%)

3. **Analyse des 5 Pourquoi** :
   - Pourquoi le service a échoué ? → Connexions de base de données épuisées
   - Pourquoi les connexions sont-elles épuisées ? → Chaque requête ouvre une nouvelle connexion
   - Pourquoi chaque requête ouvre-t-elle une nouvelle connexion ? → Le code contourne le pool de connexions
   - Pourquoi le code contourne-t-il le pool de connexions ? → Développeur peu familier avec les patterns de la codebase
   - Pourquoi le développeur n'était-il pas familier ? → Aucune documentation sur les patterns de gestion des connexions

### Diagramme système

[Client] → [Load Balancer] → [Service de paiement] → [Base de données] ↓ Pool de connexions (cassé) ↓ Connexions directes (cause)


## Détection

### Ce qui a fonctionné
- L'alerte de taux d'erreur s'est déclenchée 8 minutes après le déploiement
- Le dashboard Grafana a clairement montré le pic de connexions
- La réponse d'astreinte a été rapide (2 minutes d'accusé de réception)

### Ce qui n'a pas fonctionné
- Le seuil d'alerte des métriques de connexion de base de données était trop élevé
- Pas d'alerte corrélée au déploiement
- Le déploiement canary aurait détecté cela plus tôt

### Lacune de détection
Le déploiement s'est terminé à 14:23, mais la première alerte ne s'est déclenchée qu'à 14:31 (8 minutes). Une alerte consciente du déploiement aurait pu détecter le problème plus rapidement.

## Réponse

### Ce qui a fonctionné
- L'ingénieur d'astreinte a rapidement identifié la base de données comme le problème
- La décision de restauration a été prise décisivement
- Communication claire dans le canal d'incident

### Ce qui pourrait être amélioré
- 10 minutes pour corréler le problème au déploiement récent
- Dû de vérifier manuellement l'historique des déploiements
- La restauration a pris 12 minutes (pourrait être plus rapide)

## Impact

### Impact client
- 12 000 clients uniques affectés
- Durée d'impact moyenne : 35 minutes
- 847 tickets d'assistance (23% des utilisateurs affectés)
- Score de satisfaction client baissé de 12 points

### Impact commercial
- Perte de revenus estimée : 45 000 $
- Coût d'assistance : ~2 500 $ (temps des agents)
- Temps d'ingénierie : ~8 personnes-heures

### Impact technique
- Base de données primaire a subi une charge élevée
- Certains retards de réplique pendant l'incident
- Aucun dommage permanent aux systèmes

## Leçons apprises

### Ce qui a bien fonctionné
1. Les alertes ont détecté le problème avant les rapports clients
2. L'équipe a collaboré efficacement sous pression
3. La procédure de restauration a fonctionné régulièrement
4. La communication a été claire et opportune

### Ce qui a mal fonctionné
1. La révision de code a manqué le changement critique
2. Lacune de couverture de test pour le pooling de connexions
3. L'environnement de staging ne reflète pas le trafic de production
4. Les seuils d'alerte n'ont pas été bien calibrés

### Où nous avons eu de la chance
1. L'incident s'est produit pendant les heures de travail avec l'équipe complète disponible
2. La base de données a géré la charge sans défaillance complète
3. Aucun autre incident s'est produit simultanément

## Éléments d'action

| Priorité | Action | Propriétaire | Date limite | Ticket |
|----------|--------|--------------|-------------|--------|
| P0 | Ajouter un test d'intégration pour le comportement du pool de connexions | @alice | 22-01-2024 | ENG-1234 |
| P0 | Réduire le seuil d'alerte de connexion de base de données à 70% | @bob | 17-01-2024 | OPS-567 |
| P1 | Documenter les patterns de gestion des connexions | @alice | 29-01-2024 | DOC-89 |
| P1 | Implémenter une alerte corrélée au déploiement | @bob | 05-02-2024 | OPS-568 |
| P2 | Évaluer la stratégie de déploiement canary | @charlie | 15-02-2024 | ENG-1235 |
| P2 | Test de charge du staging avec trafic de type production | @dave | 28-02-2024 | QA-123 |

## Appendice

### Données de soutien

#### Graphique de taux d'erreur
[Lien vers snapshot du dashboard Grafana]

#### Graphique de connexion de base de données
[Lien vers les métriques]

### Incidents connexes
- 02-11-2023 : Problème de connexion similaire dans le User Service (POSTMORTEM-42)

### Références
- [Bonnes pratiques de pool de connexions](internal-wiki/connection-pools)
- [Runbook de déploiement](internal-wiki/deployment-runbook)

Modèle 2 : Analyse des 5 Pourquoi

# Analyse des 5 Pourquoi : [Incident]

## Énoncé du problème

Le service de paiement a subi une panne de 47 minutes due à l'épuisement des connexions de base de données.

## Analyse

### Pourquoi #1 : Pourquoi le service a-t-il échoué ?

**Réponse** : Les connexions de base de données ont été épuisées, causant l'échec de toutes les nouvelles requêtes.

**Preuve** : Les métriques montrent le nombre de connexions à 100/100 (max), avec 500+ requêtes en attente.

---

### Pourquoi #2 : Pourquoi les connexions de base de données ont-elles été épuisées ?

**Réponse** : Chaque requête entrante ouvrait une nouvelle connexion de base de données au lieu d'utiliser le pool de connexions.

**Preuve** : Le diff de code montre `DriverManager.getConnection()` direct au lieu de `DataSource` en pool.

---

### Pourquoi #3 : Pourquoi le code contourne-t-il le pool de connexions ?

**Réponse** : Un développeur a refactorisé la classe de repository et a inadvertamment changé la méthode d'acquisition de connexion.

**Preuve** : RP #1234 montre le changement, fait lors de la correction d'un autre bug.

---

### Pourquoi #4 : Pourquoi cela n'a pas été détecté en révision de code ?

**Réponse** : Le relecteur s'est concentré sur le changement fonctionnel (la correction du bug) et n'a pas remarqué le changement d'infrastructure.

**Preuve** : Les commentaires de révision ne discutent que de la logique métier.

---

### Pourquoi #5 : Pourquoi n'y a-t-il pas de filet de sécurité pour ce type de changement ?

**Réponse** : Nous manquons de tests automatisés qui vérifient le comportement du pool de connexions et manquons de documentation sur nos patterns de connexion.

**Preuve** : La suite de tests n'a pas de tests pour la gestion des connexions ; le wiki n'a pas d'article sur les connexions à la base de données.

## Causes racines identifiées

1. **Primaire** : Tests automatisés manquants pour le comportement d'infrastructure
2. **Secondaire** : Documentation insuffisante des patterns architecturaux
3. **Tertiaire** : La checklist de révision de code n'inclut pas les considérations d'infrastructure

## Améliorations systémiques

| Cause racine | Amélioration                      | Type       |
| ------------ | --------------------------------- | ---------- |
| Tests manquants | Ajouter des tests de comportement d'infrastructure | Prévention |
| Docs manquantes | Documenter les patterns de connexion | Prévention |
| Lacunes de révision | Mettre à jour la checklist de révision | Détection |
| Pas de canary | Implémenter les déploiements canary | Mitigation |

Modèle 3 : Postmortem rapide (incidents mineurs)

# Postmortem rapide : [Titre bref]

**Date** : 15-01-2024 | **Durée** : 12 min | **Sévérité** : SEV3

## Ce qui s'est passé

La latence API a augmenté à 5s en raison d'une tempête de cache miss après une purge de cache.

## Chronologie

- 10:00 - Purge de cache initiée pour mise à jour de configuration
- 10:02 - Alertes de latence se déclenchent
- 10:05 - Identifié comme tempête de cache miss
- 10:08 - Réchauffement de cache activé
- 10:12 - Latence normalisée

## Cause racine

Purge complète du cache pour changement mineur de configuration a causé un afflux massif.

## Correction

- Immédiate : Réchauffement de cache activé
- Long terme : Implémenter l'invalidation partielle du cache (ENG-999)

## Leçons

Ne pas purger entièrement le cache en production ; utiliser l'invalidation ciblée.

Guide de facilitation

Animer une réunion de postmortem

## Structure de la réunion (60 minutes)

### 1. Ouverture (5 min)

- Rappeler la culture sans culpabilisation
- « Nous sommes ici pour apprendre, pas pour blâmer »
- Passer en revue les normes de réunion

### 2. Examen de la chronologie (15 min)

- Parcourir les événements chronologiquement
- Poser des questions clarificatrices
- Identifier les lacunes dans la chronologie

### 3. Discussion d'analyse (20 min)

- Qu'est-ce qui a échoué ?
- Pourquoi a-t-il échoué ?
- Quelles conditions l'ont permis ?
- Qu'aurait pu le prévenir ?

### 4. Éléments d'action (15 min)

- Brainstormer des améliorations
- Prioriser par impact et effort
- Assigner les propriétaires et les dates limite

### 5. Clôture (5 min)

- Résumer les apprentissages clés
- Confirmer les propriétaires des éléments d'action
- Planifier un suivi si nécessaire

## Conseils de facilitation

- Maintenir la discussion sur le bon cap
- Rediriger la culpabilisation vers les systèmes
- Encourager les participants discrets
- Documenter les opinions divergentes
- Limiter les tangentes

Antipatterns à éviter

Antipattern Problème Meilleure approche
Jeu des blâmes Arrête l'apprentissage Focalisez sur les systèmes
Analyse superficielle Ne prévient pas la récurrence Demandez « pourquoi » 5 fois
Pas d'éléments d'action Gaspillage de temps Ayez toujours des prochaines étapes concrètes
Actions irréalistes Jamais complétées Délimitez à des tâches réalisables
Pas de suivi Les actions sont oubliées Suivre dans le système de ticketing

Bonnes pratiques

À faire

  • Commencer immédiatement - La mémoire s'estompe vite
  • Être spécifique - Horaires exacts, erreurs exactes
  • Inclure des graphiques - Preuve visuelle
  • Assigner des propriétaires - Aucun élément d'action orphelin
  • Partager largement - Apprentissage organisationnel

À ne pas faire

  • Ne pas nommer et faire honte - Jamais
  • Ne pas ignorer les petits incidents - Ils révèlent des patterns
  • Ne pas en faire un doc de culpabilisation - Cela tue l'apprentissage
  • Ne pas créer du travail inutile - Les actions doivent être significatives
  • Ne pas ignorer le suivi - Vérifier que les actions sont complétées

Skills similaires