# SLO / Error Budget — Parky

Parky の API / Mobile / Web に対する Service Level Objective (SLO) と error budget の定義・運用ルール。
2026-04-28 初版。観測性配線 (Sentry/OTel/CAE) の本格運用と同時に開始する。

## 設計方針

- **目的**: ユーザー影響の継続観測と「いつリリースを止めるべきか」を客観的に決める基準。
- **対象**: `api.parky.co.jp` (Workers BFF) を一次対象。Mobile / Web ポータルは Phase 2 で追加。
- **計測ソース**: Cloudflare Analytics Engine (CAE) + Sentry + Workers Observability。Logpush → R2 を 30 日 retention で raw データ保管。
- **窓**: 28 日ローリング (4 週)。週次レビューで burn rate を確認する。
- **error budget**: `(1 - SLO%) × 28 日のリクエスト総数` の許容失敗数。
- **alert 方針**: burn rate × 14.4 (1h で 24h 分消費) と × 6 (6h で 1日分消費) の二段アラート。

## API SLO (Tier 0 — Workers BFF)

| 指標 | 目標値 | 計測 | error budget (28 日) |
|---|---|---|---|
| **可用性** (success rate) | **99.5%** | CAE: 5xx を除く 2xx/3xx/4xx の割合 | 0.5% (例: 100 万 req/月 なら 5,000 req まで) |
| **レイテンシ p95** | **&lt; 500ms** | CAE: status &lt; 500 のみで集計 | p95 が 500ms を超えた時間の割合 ≤ 5% |
| **レイテンシ p99** | **&lt; 1500ms** | CAE: 同上 | 同上 ≤ 5% |
| **エラー率** | **&lt; 0.5%** | Sentry + CAE 5xx | 0.5% を 28 日連続で超過したら freeze |

### 除外 (SLI から除く)

- 4xx クライアントエラー全般 (`401` / `403` / `404` / `409` / `422` / `429`) — クライアント由来
- 計画メンテナンス時間中の 5xx (事前 announce + Slack 通知必須)
- 上流 (Supabase / Cloudflare 自身) の同時刻インシデント中 (Cloudflare Status / Supabase Status で確認)

## Mobile SLO (Phase 2)

| 指標 | 目標値 | 計測 |
|---|---|---|
| **crash-free sessions** | **≥ 99.5%** | Sentry Flutter |
| **cold start p95** | **&lt; 2.5s** | Firebase Performance Monitoring (要設定) |
| **検索 RPC p95** | **&lt; 300ms** | CAE で endpoint 別 |
| **OTA バージョン採用率 7 日** | **≥ 80%** | App Store / Play Store consoles |

## Web Portal SLO (Phase 2)

| 指標 | 目標値 |
|---|---|
| **LCP p75** | **&lt; 2.5s** (CrUX 月次) |
| **CLS p75** | **&lt; 0.1** |
| **JS error rate** | **&lt; 1%** of pageviews (Sentry browser SDK) |

## Error Budget 運用ルール

### 状態判定

```
budget_remaining = budget_total - errors_consumed
burn_rate_1h = errors_last_1h / budget_total
burn_rate_6h = errors_last_6h / budget_total
```

| 状態 | 条件 | アクション |
|---|---|---|
| 🟢 健康 | budget_remaining > 50% | 通常開発 |
| 🟡 注意 | budget_remaining 25-50% | 高リスク変更を要レビュー |
| 🟠 危険 | budget_remaining 10-25% | new feature freeze、信頼性改善のみ |
| 🔴 枯渇 | budget_remaining &lt; 10% | **deploy freeze**、postmortem 必須 |

### Burn rate アラート

| 条件 | 意味 | 通知先 |
|---|---|---|
| burn_rate_1h > 14.4 | 1 時間で 1 日分消費 | Slack #parky-alerts (P1) |
| burn_rate_6h > 6 | 6 時間で 1 日分消費 | Slack #parky-alerts (P2) |
| budget &lt; 25% | budget 危険 | Slack #parky-ops (Daily summary) |

### 週次レビュー (毎週月曜)

- 28 日 budget 残量
- 当週の SEV1/2 件数 + RCA 進捗
- 翌週の planned change リスク評価
- 直近 4 週の SLO trend (改善 / 悪化)

## 実装 TODO

### Phase 0 (即日)

- [ ] Sentry org 作成 + Workers/Flutter project 作成
- [ ] Sentry DSN を `wrangler secret put SENTRY_DSN` で dev/prod 投入
- [ ] Honeycomb 無料アカウント + OTLP endpoint 投入
- [ ] Cloudflare Health Checks for `/healthz` (60s 間隔, Slack alert)

### Phase 1 (1 週間)

- [ ] CAE で SLO 集計 SQL を確立 (`docs/ops/analytics-engine.md` に追記)
- [ ] 週次 cron で error budget 残量を Slack に投稿
- [ ] burn rate alert を Sentry rule で配線
- [ ] 本 doc の SLO 値を 1 ヶ月運用後に再校正

### Phase 2 (2-4 週間)

- [ ] Mobile crash-free + cold start を Sentry/Firebase で計測開始
- [ ] Web Portal LCP/CLS を Sentry browser SDK で計測開始
- [ ] Status page 公開 (オプション、`parky.statuspage.io` 等)

## 参照

- [docs/ops/incident-response.md](./incident-response.md) — インシデント対応
- [docs/ops/sentry-setup.md](./sentry-setup.md) — Sentry 設定
- [docs/ops/opentelemetry-setup.md](./opentelemetry-setup.md) — OTel 配線
- [docs/ops/analytics-engine.md](./analytics-engine.md) — CAE 集計
- [Google SRE Workbook ch.5: Alerting on SLOs](https://sre.google/workbook/alerting-on-slos/) — burn rate 設計の元ネタ
