オンコール体制 — On-Call SSoT

このドキュメントが Parky における on-call 運用の SSoT (Single Source of Truth)。 Severity 区分・Channel 振り分け・Format 標準は notification-strategy.md に従う。本 doc は 「誰が、どの device で、何分以内に、何をする」を扱う。

想定読者: Parky 開発担当本人 (1 人運用フェーズ)、将来チーム拡大時の新 joiner。


1. 設計原則 — 1 行で

1 人運用 + Discord push 二重化 で「P0 を 15 分以内に必ず ack できる」状態を作る。 PagerDuty / Opsgenie 等の専用 incident management SaaS は MAU 1 万到達まで導入しない (コスト判断)。 代わりに Discord mobile push + GH Actions failure email + Cloudflare email alert を物理経路を分けて二重化し、SPOF を作らない。

参照: project_parky_finance_state_2026_04 (残予算 2,000 万 / Burn 120 / Runway 16.7 ヶ月 → 月額 SaaS 追加は最低限)


2. ロール定義

2.1 Primary on-call

項目 内容
氏名 Parky 開発担当 (当面 1 人体制)
連絡先 [email protected] (email backup 配信先と一致)
受信 device 1 iPhone Discord アプリ (#p0-alerts の push 通知 ON、機内モード時は失敗扱い)
受信 device 2 デスクトップ Discord (作業時間中、音声通知 ON)
受信 device 3 (backup) Gmail ([email protected]) — Resend 経由の P0 backup email + GH Actions failure email
勤務時間外 当面 24/7 自分。睡眠中の P0 は「起きてから対応」を許容 (§3 参照)

2.2 Secondary on-call

  • 現状: 不在 (1 人運用)
  • 将来 (Phase 3, チーム拡大時): rotation を組む。週次担当を #p1-ops の channel topic に明示。

2.3 担当範囲

領域 Primary Secondary
API (Workers / Hyperdrive / R2) o -
Web (Pages / public / portal) o -
Supabase DB / migration o -
Cron (PLACES_WEEKLY 等) o -
Mobile (Flutter リリース後) o -
Security (secret leak / CVE) o -

3. 応答 SLA (severity 別)

Severity 応答 SLA 解決目標 備考
P0 15 分以内 ack 4 時間以内 復旧 Discord で「対応開始」reply or :eyes: reaction。睡眠中も起きたら最優先
P1 4 時間以内 翌営業日 中 営業時間内のみ、夜間は朝対応 OK
P2 翌営業日 1 週間以内 朝の Discord チェックでまとめて triage
P3 週次 review 月次 review 月曜 18:00 JST の #p3-insights digest をまとめて確認

Ack の定義 (P0)

  • Ack = 「自分が認識して対応に入った」を Discord で表明すること
  • 具体的には次のいずれか (どれか 1 つで OK):
    1. Alert message に :eyes: reaction を付ける
    2. Alert message に reply で「対応開始」「調査中」等を投稿
    3. #p0-alerts で新規 message を投稿し、status を共有

Ack ≠ 解決。Ack は「見えたよ」のシグナル。解決時は別途 thread で :white_check_mark: reaction or 「resolved」reply。


4. P0 受信の二重化 (重要)

監査指摘: 「アラートが Discord のみ → P0 を 7 日後に発見した PLACES_WEEKLY 失敗の前例あり」 → 物理経路を分けた 3 経路冗長化 で対策する。

経路 A: Discord #p0-alerts への @here mention (一次)

経路 B: iPhone Discord アプリの push 通知 (一次の届け先)

これが「夜中に音で気付く」物理経路。最重要

iPhone 設定手順 (初回のみ、5 分)

  1. iOS 設定 → 通知 → Discord
    • 通知許可: ON
    • サウンド: ON (集中モード時も鳴らすために重要)
    • バッジ: ON
    • ロック画面 / 通知センター / バナー: 全 ON
  2. Discord アプリ → ユーザー設定 (歯車) → 通知
    • Push Notifications: Enabled
    • In-App Sounds: Enabled
  3. Discord → Parky サーバー → #p0-alerts channel
    • channel 名長押し → Notification Settings
    • 設定: All Messages
    • Mute: Off (絶対 mute しない)
    • @everyone and @here: Allow (デフォルト ON、これを切ると意味なし)
  4. iOS 集中モード (Focus / Sleep) の例外設定
    • 設定 → 集中モード → 睡眠 → 通知を許可するアプリ → Discord を追加
    • これがないと睡眠モード中の P0 通知が無音化される (致命的)
  5. 動作確認
    • 月次 smoke workflow (.github/workflows/oncall-smoke.yml 参照、§7 参照) で iPhone に通知が届くことを確認

#p1-ops (P1) の push 設定

  • channel 名長押し → Notification Settings → Only @mentions
  • P1 は mention なしなので push は飛ばないが、Discord アプリを開けば未読が見える状態を維持

経路 C: Email backup (二次、Discord 障害時の保険)

C-1. Resend 経由 P0 backup email

  • 配線: notification-strategy.md §7 Layer 3
  • 条件: severity = P0 かつ Discord webhook 全 retry 失敗時のみ送信
  • 送信先: [email protected] (固定)
  • Subject: [P0 BACKUP] <title>
  • iOS Mail app の通知を ON にしておけば push で気付ける

C-2. GitHub Actions failure email (built-in)

GitHub の標準機能で workflow failure を email 通知。Discord webhook が落ちている場合の最終ラインとして稼働。

設定手順 (GitHub.com):

  1. github.com → 右上アバター → SettingsNotifications (左 sidebar)
  2. Actions セクション
    • Email: ON
    • Notify me for: Only failed workflows にチェック
    • Send to: [email protected] (primary email)
  3. iOS Gmail / Mail アプリの通知 ON

注意: GH の email 通知は per-user 設定。複数人運用時は全員が個別に設定する。

C-3. Cloudflare email alert (任意、Phase 2 で導入検討)

  • CF dashboard → Notifications → Add → 各 alert (Workers outage / Pages deploy fail / R2 quota / WAF surge)
  • Destination: email ([email protected])
  • 既に notification-strategy.md §4 に webhook 配線済みだが、CF 側 webhook 障害時の保険として email を multi-destination で並走 させる
  • 工数: CF dashboard で 10 分

経路の優先度と SLA

経路 想定遅延 障害時の挙動
A: Discord webhook < 5 sec Layer 2 retry → 失敗時 Layer 3 へ
B: iPhone Discord push < 30 sec 経路 A 成功時のみ。Discord アプリ次第
C-1: Resend backup email 1-3 min 経路 A 全失敗時のみ起動
C-2: GHA failure email 1-5 min GHA workflow 失敗時に常時並走
C-3: CF email (任意) 1-2 min CF 由来の P0 のみ、CF Discord webhook と並走

5. エスカレーション手順

5.1 1 人運用フェーズ (現状) のフロー

P0 alert 発火
  ↓
  ├─ 起きていて気付いた? → 即 ack → 対応 → resolve
  ├─ 寝ていて気付かない? → iPhone 経路 B push で起こす
  ├─ iPhone も気付かなかった (集中モード等) → 経路 C-1 / C-2 email backup で起こす
  └─ 全経路失敗 (確率限りなく 0) → 翌朝の DLQ digest (#p3-insights, 月曜 18:00 JST) で発見
                                  → postmortem 必須 (経路の見直し)

5.2 即時必要な P0 vs 翌日対応 OK な P1/P2 の判別フロー

「夜中の Discord 通知音で起きた」状況での 30 秒判断:

通知タイトルの先頭を見る
  ↓
  ├─ [P0] → 起きて即対応 (ack 15 分以内)
  ├─ [P1] → アプリで内容だけ確認、朝対応で OK (mention なしで起こされる事はない想定)
  └─ [P2] [P3] → 翌朝

重要: P0 の判定は alert rule 作成時に確定済み (notification-strategy.md §2)。 通知音で起きてから「これ P0?」と悩むのは時間の無駄。先頭の [P0] 表記だけを信じる。

5.3 Primary が応答できない場合

1 人運用フェーズ (現状)

  • 不在パターン 1: 短期不在 (旅行 / 休暇 < 1 週間)

    • 事前: #p1-ops の channel topic に「YYYY-MM-DD ~ YYYY-MM-DD 不在、緊急時は status page で告知」と明記
    • 期間中: 自動 maintenance window にはせず、P0 のみは可能な限り対応 (海外旅行中も iPhone は持つ)
    • 期間中の P1 以下: 帰宅後に triage、ユーザー影響継続中なら status page 告知 (sentry 流ステータスページ を将来構築)
  • 不在パターン 2: 緊急不能 (病気 / 事故)

    • 第三者 (家族 / 共同創業者候補) が #p0-alerts を見られる状態を作る (Discord ID 共有)
    • 第三者の役割: 「alert が来ている」事実だけ気付く役。技術対応はできなくて OK
    • 第三者経由でユーザー告知 → 復旧は復帰後

Phase 3 (チーム拡大後)

  • Primary が 30 分以内に ack しない場合、Secondary を escalate
  • Discord webhook で @<secondary-user> mention を 30 分後に自動 fire (Phase 3 で実装、現状未配線)
  • 週次 rotation を #p1-ops channel topic に固定明記

6. 月次レビュー

6.1 レビュー時刻

  • 毎月 1 日 09:00 JST (土日祝なら次の平日)
  • Calendar に reminder 登録 (Google Calendar 等)
  • 所要時間: 30-60 分

6.2 レビュー内容

過去 30 日を対象に、以下を .work/parky/oncall-review/YYYY-MM-DD_oncall_review.md に記録:

項目 確認内容
発火した P0 件数 admin.notification_failures + Sentry alerts dashboard + GHA run history を集計
応答時間の中央値 各 P0 の「発火 → ack」までの時間 (Discord reaction timestamp で測定)
SLA 達成率 15 分以内 ack の割合 (目標 100%)
見逃し / 遅延 alert 30 分以上 ack 遅延した P0 を全件列挙 → 原因分析 (デバイス / 設定 / 経路 / 集中モード)
抜けた監視 「あの障害が alert で気付けなかった」事象を列挙 → 該当 alert rule を追加
誤検知 (false alarm) P0 で発火したが実害なかった事象 → 閾値見直し
抑制ミス Cascade 抑制が効かず重複通知になった事象
DLQ 蓄積件数 admin.notification_failuresstatus='failed' の件数 (目標 < 5/月)
smoke test 結果 oncall-smoke.yml (§7) の月次実行結果 (push が iPhone に届いたか)

6.3 SLO Error Budget との連動

  • slo-error-budget.md の burn rate と本レビューの SLA 達成率を併せて見る
  • どちらかが目標未達 → 次月の優先タスク (例: alert rule 追加 / 閾値再調整 / 経路強化)

6.4 Action Item 起票

  • 改善項目は GitHub Issue で起票 (label: oncall-review, milestone: 翌月)
  • SMART 形式: Owner / 期限 / 検証方法を明記 (incident-response.md 同準拠)

7. 受信確認用 smoke workflow (任意)

P0 push が本当に iPhone に届くかを月 1 回検証する。

7.1 配線

  • Workflow: .github/workflows/oncall-smoke.yml
  • Cron: 毎月 1 日 09:00 JST (0 0 1 * * UTC)
  • 配信先: #p0-alerts (P0 channel) に @here 付き smoke message
  • 形式: [SMOKE] On-call 受信確認 YYYY-MM-DD + 「iPhone push が届いた? Discord で :eyes: reaction を付けてください」

7.2 確認手順

  1. 月初にこの smoke message が iPhone に push される
  2. push 通知音で気付いたら :eyes: reaction を付ける
  3. 24 時間以内に reaction が付かない → 翌月の月次レビューで「設定見直し」を action item 化

7.3 手動 trigger

緊急時 (デバイス変更後等) は workflow_dispatch で即時実行可能:

gh workflow run oncall-smoke.yml

8. 移行プラン

Phase 1 — 現状 (~MAU 1 万)

  • コスト: $0/mo
  • 構成: Discord webhook + iPhone push + Resend backup email + GHA email + (任意) CF email
  • 想定 SLA: P0 15 分 ack 95% 以上

Phase 2 — MAU 1 万到達後 (Parky phase_strategy Phase 1 中盤)

  • PagerDuty Pro plan 検討 ($21/user/mo)
    • 機能: SMS / 電話 escalation / on-call rotation / 自動 escalation
    • 採用条件: Discord push の miss 率 > 5% (月次レビュー集計) または P0 件数 > 月 5 件
    • 不採用条件: 上記未達なら継続して Discord メイン
  • Status page 構築 (Better Uptime Free or Atlassian Statuspage Free)
    • customer-facing 透明性の向上 (status.parky.co.jp)
    • on-call 不在時のユーザー告知導線

Phase 3 — チーム拡大後 (2-3 人体制)

  • Rotation 開始: 週次 primary / secondary を #p1-ops topic で明記
  • 自動 escalation 配線: Primary が 30 分以内 ack しないと Secondary に mention
  • PagerDuty 本格運用: rotation を PagerDuty 側で管理、Discord は配信先の 1 つに格下げ
  • 月次レビュー: チーム全員参加、postmortem は必ず blameless

9. 関連 doc

このドキュメントが on-call 運用 SSoT。以下は関連 runbook / 設計:

監査根拠

  • 2026-04-29 監査指摘: 「Discord 単一経路で P0 見逃しリスク (PLACES_WEEKLY 7 日後発見の前例)」 → 本 doc 作成で iPhone push + email backup の二重化を文書化

変更履歴

  • 2026-04-30: 初版作成。M-4 監査対応 (オンコール体制 doc 整備)。 Discord + iPhone push + email 三重化、月次レビュー、PagerDuty 移行プランを定義。
↗ Source markdown (oncall.md)