# Codex Adversarial Review (8回目) — Decision ADR v2 検証

- 対象: `19_v4_Decision_ADR_v2.html`
- 実行日: 2026-04-17
- Verdict: **needs-major-revision**（9回目が必要、ただし focused patch で可）
- Codex 自身のコメント: "A 9th round is needed, but it should be a targeted blocker patch, not another broad rewrite"

---

## Findings（6件、うち critical 1）

### 🔴 [critical] MEK rotation が PITR restore で復号不能を引き起こす
**場所**: §9.3 MEK Rotation フロー

Rotation flow は「全 store 移行後に V4_MEK_V1 を削除」と書くが、9.6 Restore 挙動では「old MEK は最低 30日保持」と書いた。**矛盾**: rotation 後に V1 を削除すると、Neon PITR で rotation 前に戻した場合、restored rows が v1 を参照するので IG token 全部復号不能。

さらに batch job の詳細不足: per-row version guards / tombstone / resumability / concurrency protection が未定義。

**Recommendation**:
- **old-MEK 保持を明示的に invariant 化**: max(PITR window = 7日, restore-drill lag, incident investigation hold) + buffer = 最低 90日保持
- **Rotation job の仕様**:
  - `WHERE mek_version = 'v1'` 条件付き idempotent batch
  - row-level transaction
  - deleted-store 除外
  - audit エントリ
  - retry/resume state
  - 完了後の PITR restore drill で復号検証

---

### 🟠 [high] TCO が未検証 flat price で構築、β/γ のコスト結論が defensible でない
**場所**: §5.2〜5.3

Codex が**公式サイトで実価格を確認**:
- Neon: **usage-based**（Launch $0.106/CU-hr、Scale $0.222/CU-hr、typical Scale は $701/月）
- Trigger.dev: plan + run invocation + compute seconds
- Better Stack: SMS/on-call responder は $34/月〜
- Clerk: **MRU/MRO/add-on 課金**、300店舗で Organizations 使用なら 100 included MRO を超過

→ β/γ の 1.6% 差主張は**根拠なし**。

**Recommendation**:
- vendor-verified usage model に置換:
  - Neon CU-hour / storage / restore-window assumption
  - Trigger.dev run count / runtime
  - Better Stack responder / status-page
  - Clerk MRU / MRO / add-on
- 再計算後、「コストは決定要因ではない」主張が成立するか再確認

**参照元**:
- https://neon.com/pricing
- https://trigger.dev/pricing
- https://betterstack.com/pricing
- https://clerk.com/pricing

---

### 🟠 [high] INV-18 が launch-blocking unknown のまま + E9 が Trigger.dev Cloud で通過不可
**場所**: §4 スコア + §10.9 E9

ADR は INV-18 を Unknown としながら γ を advance。E9 は「Neon/Clerk/Trigger.dev/R2 を JP region、PII が region を出ない証明」を要求。

**Codex 実調査**: Trigger.dev の docs 明記 "run region は code 実行場所のみを制御、run payload / output / tag / log などのデータ保存場所は変わらない"。→ **Trigger.dev Cloud を使う限り、Trigger に PII/secrets を入れない設計でない限り E9 は pass 不可**。

**Recommendation**:
- **INV-18 を pre-Q1 blocker に昇格**、または
- **Trigger.dev に opaque ID のみ渡す設計に制約**（PII/secrets を渡さない）し、vendor DPA / region evidence を添付
- それが不可なら self-hosted Trigger.dev or 案β に切替検討

**参照元**: https://trigger.dev/docs/triggering

---

### 🟠 [high] Failure matrix が desired outcome のリストで、executable な evidence plan でない
**場所**: §10 E1〜E9

- E2: 6 crash timing を列挙しているが、**prototype で実際にどう crash を誘発するか**未定義（Workers 環境で SIGKILL injection は困難）
- E4: "Mock IG 500 / rate limit" と書いたが mock 境界と Trigger.dev outage シミュレーション手段未定義
- E5: "10 min/store rollback" と Neon Branch 利用を主張するが reverse migration / dual-write reconciliation / conflict handling が未証明
- Week 2 で E1-E9 minimum 実装と pass/fail を要求しているが、test harness 不足で非現実的

**Recommendation**: ADR 送付前に test mechanics を具体化:
- injectable failpoints（各 DB/API 境界）
- local IG mock service（例: wiremock or MSW）or controlled adapter
- Trigger outage simulation 戦略（feature flag による意図的停止 or test-only trigger client）
- migration rollback scripts の骨格
- expected artifact（Postgres row の state, log 出力例）
- Week 2 で gate する subset と implementation phase に回す subset の明示

---

### 🟠 [high] 24/7 モデルが子安氏の同意・コミットなしに組まれている
**場所**: §12 Operating Model + §13 子安氏への質問

rota は子安氏を weekday 9-19 primary + 19-9 overnight + 週末 rotation に割り当てているが、**Q1-Q5 に「on-call 受諾」「手当」「escalation 負担」を含む質問が欠落**。

P1 response 30分 + 1h RTO は secondary escalation timer / missed-page procedure / 内部 buffer がない。8 runbook は列挙のみ、未作成。

**Recommendation**:
- Q6 として「on-call rota + compensation + escalation acceptance」を追加
- prototype or Week 3 開始の gate に以下を足す:
  - drafted P1/P2 escalation policy
  - missed-page → secondary timeout
  - Better Stack responder/SMS cost 確認
  - minimum viable runbook 6本（publish outage / Clerk / Neon / Trigger / MEK compromise / rollback）のドラフト

---

### 🟡 [medium] γ の composite availability 許容に margin が 7分しかない
**場所**: §6.3 INV-16 劣位の受容条件

Clerk 99.9% × Neon 99.95% × Trigger.dev 99.9% × CF 99.99% = 99.74% = 月 113分 downtime。SLO 120分。**margin 7分のみ**。

Instagram/Meta、Anthropic、Sentry、Better Stack、planned maintenance、相関 outage は計算に入っていない。degraded mode は prose only で test もない。

**INV-16 の劣位を INV-17 で補償する**主張は根拠不足。

**Recommendation**:
- 案β を availability margin で選ぶ、または
- downtime SLO を relax（月 240分 / 99.46% 等）、または
- **全 critical vendor + planned maintenance を含む real error-budget calculation**
- INV-17 に degraded-mode の**具体的な behavior と test**を含める

---

## Next Steps（Codex 最終推奨）

1. **19 を as-is で子安氏に送らない**
2. **targeted blocker patch（19.1）** を作成:
   - TCO を vendor-verified usage model で再計算
   - INV-18 を real gate に
   - MEK retention/rotation 修正
   - E2〜E5 を executable test mechanics に
3. **9回目 review は上記 blocker のみを narrow に**

---

## CC 側のアクション見積

| Finding | 修正内容 | 時間 |
|---|---|---|
| 1 (critical) | MEK retention 90日保持ルール + rotation job 仕様明示 | 1.5h |
| 2 (high) | TCO を vendor 実価格で再計算（Neon CU-hour / Trigger.dev run billing / Clerk MRU / BetterStack responder） | 3h |
| 3 (high) | INV-18 pre-Q1 gate 化 + Trigger.dev に opaque ID のみ渡す設計制約（or self-host検討） | 2h |
| 4 (high) | E2-E5 に failpoint / mock service / rollback script の具体化 | 3h |
| 5 (high) | Q6 on-call acceptance 追加 + 8 runbook のうち 6本ドラフト（最低限の手順） | 3h |
| 6 (medium) | INV-16 再評価（β or SLO relax or error budget math） | 1h |
| | **合計** | **13.5h** |

### 重要な発見: case-by-case の「再計算」で結論が変わる可能性

TCO 再計算次第で β と γ の差が 1.6% ではなく **数十 % 差** になる可能性。その場合 Decision が β に切替わるかもしれない。INV-18 で Trigger.dev が使えないなら、**γ 自体が reject** される可能性もある。

→ 本 patch は「Decision を補強する」ではなく「**Decision を再検証する**」作業になる。
