型付き辺: 出 13 / 入 0
ADR-0052: Decision Pipeline UI: retroactive validation モード + create-pr 確認 dialog
- Status: Accepted
- Mode: Standard
- Scope: platform
- Kruchten Type: Existence/Property
- Implementation Status: Done (PR #841)
- 起案者: [email protected]
- 起案日時 (JST): 2026-05-19 00:14
- 承認日時 (JST): 2026-05-19 00:35
- Deciders: [email protected] (単独)
1. コンテキスト
1.1 背景 (Background)
Decision Pipeline (ADR-0019) の chat UI で、retroactive validation 用途と通常の新規起案用途の区別がない。ADR-0050 retroactive validation (2026-05-18) 実行時、代表取締役氏が誤って /chat/create-pr を呼んでしまい、不要な PR #821 が自動生成された。ADR-0050_retroactive_validation_prompt.md Step 7 で「retroactive 時は PR 作成禁止」と明記されていたが UI 側にガードがなく、操作ミスで発火した。
参照: docs/_internal/03_decisions/decision_pipeline/ADR-0050_gate4_validation_report.md §6.4 (Pipeline UI 改善余地、別 ADR 候補と明記)。
1.2 現状 (Current State / As-Is)
- chat UI (chat.html) には retroactive validation モードの識別機構がなく、draft アップロード時も種別を問わない
POST /chat/create-prは draft の種別を問わず即実行され、サーバ側のガードも無し- create-pr ボタンは confirm() なしで即発火する
1.3 課題 (Problem)
- retroactive validation モードの draft が UI で識別できない
- create-pr が confirm() なしで即実行される (誤クリック耐性ゼロ)
- 「retroactive のつもりが PR 作成された」事故のフォールバックが PR 取り消ししかない (PR #821 churn コスト発生済)
1.4 制約・要件 (Constraints & Requirements)
- bizlp 既存方針「不可逆操作は技術的にブロック」(CLAUDE.md Prohibited 末尾、
PreToolUseHook) との整合必須 - 過去 draft との後方互換性維持 (KV payload
retroactive?はデフォルト false) - 変更対象は
drp/src/index.ts(30 行) +50 行) に限定drp/public/chat.html( - chat-terminal.html は本 ADR 対象外 (利用頻度低、後日同期する別 PR で対応)
- ADR-0019 / ADR-0037 を Refines し、supersede しない
1.5 目標 (Goals / To-Be)
- retroactive validation モード draft を UI banner + サーバ 422 guard で二重に識別・ブロックする
- 通常 draft でも create-pr 時に confirm dialog を表示し、誤クリック耐性を確保する
- Non-Goals: chat-terminal.html の同期、retroactive 専用ページ分離 (
/chat-retroactive)、metadata-only 管理への移行
2. 決定
drp に以下 2 機能を追加する。
(A) Retroactive validation モード
POST /draftsでretroactive?: booleanを受け取り、payload + KV metadata に保存GET /drafts/GET /drafts/:idレスポンスにretroactiveを含める- フロント (chat.html) で draft アップロード時に「これは retroactive validation 用ですか?」を confirm() で問う
- draft ロード時に
retroactive: trueを検出したら:- 上部に banner 表示 (🔒 Retroactive validation mode — PR 作成は無効化)
- 結果画面で create-pr ボタンを非表示、代わりに notice 表示
- サーバ側
POST /chat/create-prでdraft_idから KV を引き、retroactive: trueなら 422 Unprocessable Entity を返す (defense-in-depth)
(B) create-pr 確認 dialog
- retroactive でない場合も、create-pr ボタンクリック時に
confirm('GitHub に PR を作成します。よろしいですか?')を表示 - 誤クリック耐性を確保
判断基準は ADR-0050 で確立した arc42 Q42 9 タグ + WSM + K.O. criterion (CBA Suhr 1999) を本 ADR にも適用し、Synthesis 文書だけでなく ADR 起案にも MCDA を導入する第一適用例とする。
2.1 評価軸 (Q42 5 軸選定、ADR-0050 §4.2 準拠)
| # | 軸 | 重要度 (係数) | 案件特有の解釈 |
|---|---|---|---|
| 1 | #reliable | [Must] (×2.0) | retroactive validation の安全性、PR 自動生成事故 (PR #821) の構造的防止 |
| 2 | #operable | [Must] (×2.0) | bizlp 既存「不可逆操作は技術的にブロック」方針 (CLAUDE.md Prohibited 末尾、PreToolUse Hook) との整合 |
| 3 | #maintainable | High (×1.0) | chat.html / src/index.ts の保守負荷、UI 差分の管理コスト |
| 4 | #suitable | High (×1.0) | ADR-0019/0037 を Refines する既存資産との整合性 |
| 5 | #usable | Medium (×0.5) | 誤クリック耐性、起案者の認知負荷 (dialog のうざさ vs 安全性のトレードオフ) |
K.O. criterion: Must 軸 (#reliable / #operable) の score < 3 は不採用 (機能要件未充足とみなす)。
2.2 評価軸 × 案スコア表
| 軸 | 係数 | 採択案 (A+B 統合) | 案 A1 フロントのみ | 案 A2 別エンドポイント | 案 A3 dialog のみ |
|---|---|---|---|---|---|
#reliable [Must] | ×2.0 | 5 (frontend 非表示 + server 422 二重ガード) | 2 (改竄可能) | 4 (隔離) | 2 (mode 区別なし) |
#operable [Must] | ×2.0 | 5 (技術ブロック方針整合) | 1 (方針不整合) | 4 | 1 |
#maintainable High | ×1.0 | 4 (~80 行追加、単一 endpoint 拡張) | 5 (~30 行) | 2 (API 二重化) | 5 (~20 行) |
#suitable High | ×1.0 | 5 (Refines 明示) | 3 | 3 (新規 endpoint で別文脈) | 3 |
#usable Medium | ×0.5 | 5 (mode banner + dialog 両方) | 2 | 3 | 4 (dialog のみ) |
| 加重和 (正規化、満点 32.5) | 0.969 | 0.462 | 0.692 | 0.492 | |
| K.O. 通過 (Must 軸 ≥3) | ✓ | ❌ (#operable=1) | ✓ | ❌ (#operable=1) |
加重和首位 = K.O. 通過案 = 採択案 (A+B 統合)。
Note: 加重和は絶対判定ではなく、K.O. 通過候補のタイブレーク・透明性確保用 (Suhr 1999 CBA criterion)。本案件では K.O. 通過 2 案 (採択案 / 案 A2) のうち、加重和差 0.277 ポイントが明確に採択案を支持。
3. 検討した代替案 (Alternatives Considered)
- 案 A1: フロント側のみで実装 (server-side guard なし) — 不採用理由: フロント JS は改竄可能で、retroactive モードの draft が偶発的に create-pr を呼んだ場合の構造的防止にならない。bizlp の「不可逆操作は技術的にブロック」方針 (CLAUDE.md Prohibited 末尾、
PreToolUseHook 強制ブロック) と不整合。K.O. 不通過 (#operable=1)。 - 案 A2: 別エンドポイント
/chat/retroactive-validateを新設 — 不採用理由: API 二重化で保守負荷増 (#maintainable=2)、#operableは通過するが採択案より低スコア。retroactive flag はあくまで draft メタ情報であり、既存/chat/startで同じ Gate 0-4 処理を流用できる。KV ベースの flag 管理が最小実装 (YAGNI)。 - 案 A3: 確認 dialog のみ追加 (retroactive flag は実装しない) — 不採用理由: 誤クリック耐性は得られるが、retroactive validation の本来の運用 (PR 作成しない) を UI レベルで明示できない (#reliable=2)。事故再発時に「retroactive のはずが confirm で OK 押してしまった」リスクが残る。ADR-0050 §6.4 が指摘した両側 (mode + dialog) の対応が必要。K.O. 不通過 (#operable=1)。
4. コスト試算
- サーバ実装 (src/index.ts): 1-2 時間
DraftMeta拡張、POST /draftsbody 拡張、/chat/create-prguard 追加
- フロント実装 (chat.html): 2-3 時間
- upload 時の confirm()、hidden field 追加、banner UI、create-pr 非表示分岐、confirm dialog
- テスト + デプロイ: 1-2 時間
- retroactive=true / retroactive=false の draft で動作確認、wrangler deploy
- ドキュメント更新: 1 時間
- operator_guide.md に retroactive mode セクション追加
- 合計: 5-8 時間 (Standard 想定)
- 運用コスト: 追加なし (UI クリック 1 回増 = ms オーダー)
5. 影響 (Consequences)
5.1 正の影響 (Good)
- ADR-0050 §6.4 で識別された UI 改善余地に対応
- 操作ミス起因の事故 (PR #821) の構造的再発防止 (server-side 422 + フロント非表示の二重ガード)
- KV metadata 拡張で将来の draft 種別 (dry-run / dev-test 等) への拡張余地
- Pipeline 自己審査フロー (retroactive validation) の運用基盤強化
5.2 負の影響 (Bad)
- KV payload スキーマ変更 (
retroactive?追加) で過去 draft との互換性は保つ (デフォルト false) が、operator_guide.md 等の運用ドキュメント更新が必要 - フロント側に新規 hidden field + banner UI 追加で chat.html が ~50 行増 (1245 → ~1295 行)
- chat-terminal.html との UI 差分が一時的に発生 (本 ADR では対象外、後続 PR で同期)
5.3 中立・トレードオフ (Neutral / Trade-offs)
- retroactive flag が draft 側にだけあって UI 側で読み飛ばされた場合、create-pr が走る可能性 → server-side 422 guard で defense-in-depth
- KV
getWithMetadataの eventual consistency (~60s) で flag 反映遅延の可能性 → payload にも retroactive を含めることで.get()でも判定可能 - 確認 dialog の追加で「うざい」体感が出る可能性あり (cf. §6 撤退条件で
confirm-only-when-riskyモードへの fallback 余地)
6. 撤退条件 (Rollback Plan)
- 3 ヶ月後 (2026-08-18): retroactive validation 件数 / 全 draft 件数 比率を確認、10% 未満なら機能の意義を再評価
- 6 ヶ月後 (2026-11-18): 422 guard が実際に発火した回数を計測、ゼロなら過剰実装として簡素化検討 (フロントガードのみに縮退)
- 1 年後 (2027-05-18): chat-terminal.html との UI 差分が運用上問題になっていれば共通化リファクタを別 ADR で起案
- 確認 dialog が「うざい」と代表取締役氏が判断したら、retroactive 時のみ dialog 表示する
confirm-only-when-riskyモードへ fallback (UI 設定追加) - KV payload に retroactive 追加が将来の schema migration を阻害したら、metadata-only 管理へ移行 (
.getWithMetadata()ベース)
Review After: 2026-08-19 (3 ヶ月後) / 2026-11-19 (6 ヶ月後) / 2027-05-19 (1 年後)
6.1 半年〜1 年後の負債化リスク
- chat.html と chat-terminal.html の UI 差分拡大 → 共通化リファクタが必要に。本 ADR は意図的に chat-terminal 対象外とするため、運用上の「片方しか直っていない」混乱が発生する可能性 → README で明示
- KV payload に retroactive を含める設計 vs metadata-only 管理のどちらが正解か、6 ヶ月後の運用実態で判定
- 「retroactive 時の特殊扱い」が増えると UI の認知負荷が増加 → 別ページ
/chat-retroactive分離も検討候補 (現時点では YAGNI)
6.2 検証可能な完了条件
drpのwrangler deployが成功- chat UI で retroactive=true でアップロードした draft をロード → banner 表示 + create-pr ボタン非表示を目視確認
- retroactive=false の draft をロード → 通常通り create-pr ボタン表示、click 時に confirm() dialog 表示を目視確認
POST /chat/create-prを retroactive=true の draft_id で呼ぶと HTTP 422 が返ることを curl で確認operator_guide.mdに retroactive mode セクション追記、参照リンク追加- 既存 PR (#821 のような) と本機能の関係を ADR 本文の「過去事故との関係」で説明
Confirmation (準拠確認 / Fitness Function)
- 検証手段 (自動):
drp/test/に integration test を追加し、(1)POST /draftswithretroactive: true→GET /drafts/:idのレスポンスにretroactive: trueが含まれること、(2) 当該 draft_id でPOST /chat/create-prを呼ぶと HTTP 422 が返ること、を assert する。CI (GitHub Actions) で PR ごとに実行。 - 検証手段 (手動): PR レビュー時に reviewer が chat.html のロード動作を localhost で目視確認 (retroactive=true → banner 表示 + create-pr 非表示、retroactive=false → confirm dialog 発火)。チェックリストを PR template に追加。
- 実行頻度: 自動 = PR ごと (CI) + main push ごと、手動 = retroactive validation 関連の変更を含む PR 時。運用統計 (422 発火回数、retroactive draft 比率) は §6 Rollback Plan の 3/6 ヶ月レビューで集計。
- 違反時の対応: CI 失敗時は PR merge ブロック。本番で 422 guard をすり抜けて PR が誤生成された場合は、即座に該当 PR を close + ブランチ削除し、postmortem を
docs/_internal/03_decisions/decision_pipeline/に記録、本 ADR を Superseded 候補として再評価。
7. 参照 (References)
- 関連 ADR:
- ADR-0019 (Decision Pipeline LangGraph 移行) を Refines: 本 ADR は ADR-0019 末尾の補強として位置付け、UI 安全性レイヤを追加。ADR-0019 を supersede しない (基本アーキテクチャは不変)。
- ADR-0037 (KV draft staging) を Refines: 既存の DRAFTS_KV スキーマに
retroactive?: booleanフィールドを追加 (互換性維持、デフォルト false)。 - ADR-0050 (Synthesis 標準テンプレート) Gate 4 validation report §6.4 で識別された Pipeline UI 改善余地への直接対応 (本 ADR の起案根拠)。本 ADR は ADR-0050 の Q42 9-tag MCDA を ADR 起案にも適用する 第一適用例として位置付け。
- 関連 PR/Issue:
- PR #821 (2026-05-18, 誤って自動生成され即 close) — 本 ADR で再発防止対象。
- 外部資料:
- Suhr, J. (1999) The Choosing By Advantages Decisionmaking System — K.O. criterion / WSM の出典。
- arc42 Quality Requirements (Q42) 9-tag 体系。
docs/_internal/03_decisions/decision_pipeline/ADR-0050_gate4_validation_report.md§6.4。docs/_internal/03_decisions/decision_pipeline/ADR-0050_retroactive_validation_prompt.mdStep 7。CLAUDE.mdProhibited 末尾「不可逆操作は技術的にブロック」方針 /PreToolUseHook。