# Postmortem Template — Parky

ポストモーテム (RCA / Root Cause Analysis) の標準テンプレート。
SEV1/SEV2 インシデント発生時に必ず作成する。配置場所: `docs/ops/postmortems/YYYY-MM-DD-<short-title>.md`

> 目的: 個人攻撃ではなく、システムとプロセスの改善。**Blameless Culture** で書く。
> 「Aさんがミスした」ではなく「`X 状況下で Y を防ぐ仕組みが無かった`」と表現する。

---

## メタ情報

| 項目 | 値 |
|---|---|
| **タイトル** | <一言で何が起きたか> |
| **発生日時 (JST)** | YYYY-MM-DD HH:MM:SS |
| **検知日時 (JST)** | YYYY-MM-DD HH:MM:SS |
| **解消日時 (JST)** | YYYY-MM-DD HH:MM:SS |
| **継続時間** | NN 分 |
| **Severity** | SEV1 / SEV2 / SEV3 |
| **影響範囲** | `api.parky.co.jp` / `admin.parky.co.jp` / mobile app / etc |
| **影響ユーザー数** | 推定 NN 人 / NN req / NN session |
| **検知方法** | Sentry / CF Health Check / ユーザー報告 / その他 |
| **作成者** | <name> |
| **レビュアー** | <name> |
| **作成日** | YYYY-MM-DD |

---

## 1. インシデント概要 (Summary)

100 文字程度で「何が起きたか」を要約。技術詳細は後段で。

例: `2026-04-28 10:32 〜 10:45 (13分間)、api.parky.co.jp の 5xx エラー率が 0.5% → 8.2% に急増。原因は新規 deploy された wrangler.toml の binding 設定漏れ。rollback で解消。`

---

## 2. 影響 (Impact)

- **ユーザー影響**: 何ができなかったか / 誰に影響したか
- **ビジネス影響**: 売上 / 機会損失 / SLA 違反 / 信頼低下
- **データ影響**: 整合性 / 損失 / 漏洩
- **運用影響**: 対応に要した工数 / 後続作業への影響

定量化できるものは数値で。「不明」も明記する。

---

## 3. タイムライン (Timeline)

時系列で実際に起きたこと + 対応を記述。**JST 時刻 + 出来事 / アクション**。

| 時刻 (JST) | イベント |
|---|---|
| 10:32:00 | wrangler deploy 完了 (commit abc1234) |
| 10:32:15 | Workers 5xx alert が #parky-alerts に発火 |
| 10:32:45 | <name> がチャネルで応答、調査開始 |
| 10:35:00 | Sentry で `STATE_HMAC_SECRET undefined` が原因と特定 |
| 10:38:00 | wrangler rollback 開始 |
| 10:42:00 | rollback 完了、5xx エラー率が 0.5% に復帰 |
| 10:45:00 | インシデント終息確認、ステークホルダー通知 |

### 検知遅延 / 対応遅延の分析

- 検知から認知まで何分? なぜ?
- 認知から対応開始まで何分? なぜ?
- 対応開始から解消まで何分? なぜ?

---

## 4. 根本原因 (Root Cause)

「なぜ?」を 5 回繰り返して掘る (5 Whys)。

例:
1. **Why?** Workers が起動時に throw した
2. **Why?** `STATE_HMAC_SECRET` が undefined だった
3. **Why?** wrangler.toml の `[env.prod] vars` セクションに登録されていなかった
4. **Why?** secret は CI で `wrangler secret put` 経由で投入する設計だが、新マシンで rotate 後に prod 環境への投入がスキップされた
5. **Why?** secret rotation のチェックリストに環境別投入の項目が無かった

### 直接原因 (Trigger)

何が引き金になったか (具体的な操作 / イベント)。

### 寄与要因 (Contributing factors)

直接原因ではないが、被害を拡大した / 検知を遅らせた要素。

例:
- prod 環境ガード (GitHub Environment 承認) が未設定だったため誤 deploy がそのまま流れた
- Sentry alert の SLA が 5 分間隔で集計されており、検知が遅延した
- on-call rotation が無く、たまたま気付いた人が対応した

---

## 5. 解消方法 (What fixed it)

実際に効いた対応。試したけど効かなかったものも記録 (次回の参考)。

- ✅ 効いた: `wrangler rollback --env prod` で前 commit へ戻す
- ❌ 試したが効かず: `wrangler secret put STATE_HMAC_SECRET --env prod` (新 deploy の方が古い deploy を上書きしないため)

---

## 6. 良かった点 (What went well)

恥ずかしがらずに書く。再発防止 / 文化醸成のため。

- Sentry alert が 15 秒で発火し、認知まで遅延がなかった
- runbook の `wrangler tail` コマンドが即座に役立った
- rollback 手順が docs に明記されていたため迷わなかった

---

## 7. 改善できた点 (What didn't go well)

- prod 環境ガードが無く、push が即 deploy された
- Sentry の Issue grouping が雑で 5xx の根本原因特定に時間を要した
- on-call が居らず、たまたま気付いた人 (担当外) が対応した

---

## 8. アクションアイテム (Action items)

**SMART** (Specific / Measurable / Assignable / Relevant / Time-bound) に書く。
「気をつける」「徹底する」は禁止フレーズ — 仕組みに落とす。

| ID | アクション | 担当 | 期限 | Issue / PR |
|---|---|---|---|---|
| AI-1 | `STATE_HMAC_SECRET` を `assertRequiredSecrets()` で起動時 assert | hf | 2026-04-30 | #N |
| AI-2 | secret rotation チェックリストに「環境別投入確認」項目追加 | hf | 2026-04-29 | docs PR |
| AI-3 | GitHub Environment `production` に required reviewer 設定 | hf | 2026-04-29 | UI 操作 |
| AI-4 | wrangler.toml の var 不足を CI で事前検出する `assertWranglerVars()` チェック追加 | hf | 2026-05-05 | #N |
| AI-5 | on-call rotation の運用開始 (週次担当指定) | hf | 2026-05-15 | docs PR |

各 AI には **Owner / 期限 / 検証方法** を必ず付ける。

---

## 9. 教訓 / 文化的発見 (Lessons learned)

技術以外の学び。組織 / プロセス / コミュニケーション。

- secret rotation のような「滅多にやらない手順」は checklist 化が必須
- 1-dev shop でも environment guard は欠かせない
- monitoring の alert 文言は対応者が次に何をすべきか書く方が良い

---

## 10. 関連リンク

- 対象 commit: <git URL>
- Sentry issue: <URL>
- Slack スレッド: <URL>
- 影響を受けた endpoint の docs: <URL>
- 関連 ticket: <URL>

---

## レビュー署名

- Author: <name> <date>
- Reviewer: <name> <date>
- Approved: <name> <date>

---

> **このテンプレートの維持**: フィールドの過不足はレビュアーが指摘して都度更新する。
> ポストモーテムは inert artifact ではなく、改善の起点。AI が closed されるまでオーナーが追跡。
