• Status: Accepted
  • Mode: Standard
  • Kruchten Type: Property/Executive
  • Scope: platform
  • Implementation Status: Done (PR #1160 / #1162 / #1164)
  • 起案者: [email protected]
  • 起案日時 (JST): 2026-05-29 23:15
  • 承認日時 (JST): 2026-05-29 23:20 (Pipeline 通常 flow Standard 45/50 通過 + Cross-Validation/Consistency/Policy INFO、PR #1148 マージ)
  • Deciders: [email protected] (単独)

コンテキスト

§1.1 背景

Decision Pipeline は 1 起案あたり平均 ~6.7 分かかるが、chat UI は実行中ステップ進捗しか表示せず、各 Gate の結果内容(盲点・整合性・並列レビュー・スコア)は完了まで見えず最後に一括表示される。起案者は数分間、中間結果(特に Gate1 盲点・Gate2 CONFLICT)を見られず早期の中断・方針修正ができない。

§1.2 現状 (As-Is)

ステップ進捗は live 稼働(chat.html setStepFromGateProgress//chat/status ポーリング)だが、consumer は gate ごとに status のみ DO に書き、結果は status:'complete' 時に最終 result だけ patch(pipeline_consumer.ts:195)。pollSessioncomplete でしか showResult を呼ばない。

§1.3 課題

平均 6.7 分の待機中、起案者は Gate1 盲点や Gate2 CONFLICT を把握できず、本来であれば早期に中断・方針修正できる起案も最後まで実行される。中間結果の不可視が無駄な待機と意思決定遅延を生んでいる。

§1.4 制約・要件

  • 既存基盤(LangGraph stream events / Durable Object / ポーリング / ステップ UI)の延長で実現する
  • DO value 上限 128KB に収まる(session 合計 ≤64KB、各 gate ≤8KB に切り詰め)
  • feature flag PROGRESSIVE_GATE_RESULTS で ON/OFF 切替可能・即時ロールバック可
  • 追加 LLM コストを発生させない
  • 並列 gate 書込時の race を merge セマンティクスで防ぐ

§1.5 目標 (To-Be)

各 Gate 完了時にその部分結果を DO へ patch し、UI が到着順に逐次描画する。暫定/確定バッジで中間↔最終の誤認を防ぐ。Non-Goals: SSE/WebSocket への移行、ステップ進捗 UI の刷新。

決定

各 Gate 完了時に consumer の LangGraph stream イベント(pipeline_consumer.ts:150/156)で gate 出力を partialResults[gate] として DO に key 単位 merge patch し、pollSession(chat.html:2581 付近)で逐次描画する。各 gate パネルに「暫定」バッジを付け complete 時に「確定」へ遷移。エラー時は lastSuccessfulGate を記録し UI に「Gate X まで完了/Gate Y 失敗」を表示。feature flag PROGRESSIVE_GATE_RESULTS(env var or KV)で ON/OFF を制御。

判断基準 (Decision Drivers)

3.1 評価軸

#重要度 (係数)案件特有の解釈
1#usable[Must] (×2.0)6.7 分の待機中に中間結果が見え、早期判断ができる
2#maintainable[High] (×1.0)既存基盤(LangGraph stream / DO / ポーリング)の延長で実装・保守できる
3#reliable[High] (×1.0)並列 gate 書込 race・DO サイズ上限・暫定/確定整合の信頼性
4#efficient[Medium] (×0.5)DO write +~7/session・storage 増を許容範囲に抑える
5#flexible[Medium] (×0.5)feature flag で ON/OFF・ロールバック可能

K.O. criterion: Must 軸 (#usable) の score < 3 は不採用。

3.2 評価軸 × 案スコア表

各案 0-5 で評価。加重和 = (Σ score × 係数) / (満点 × Σ 係数) で正規化 (0.0-1.0)。

係数採択案 (progressive streaming + flag)案 A (現状維持 + UX 説明文追加)案 B (Gate 完了時 toast 通知のみ)
#usable×2.0413
#maintainable×1.0454
#reliable×1.0354
#efficient×0.5354
#flexible×0.5534
加重和 (正規化)0.7500.6200.720
K.O. 通過 (Must ≥3)

加重和は K.O. 通過候補のタイブレーク用 (Suhr 1999 CBA 準拠)。

検討した代替案 (Alternatives Considered)

  • 案 A (現状維持 + UX 説明文追加): chat UI に「実行中は別タスクへ切替推奨」等の説明文のみ追加(1 時間未満)— #usable で K.O. 不通過。中間結果の不可視という課題自体は未解決。
  • 案 B (Gate 完了時 toast 通知のみ): gate 完了時に簡易 toast を出すのみで結果内容は表示しない — 視認性は一部改善するが結果の中身が見えず早期判断には不十分(#usable score 3)。加重和も採択案より低い。
  • 案 C (SSE/WebSocket 移行): ポーリングを廃止し push 通信へ移行 — #maintainable で大幅な実装変更が必要、本起案のスコープ超過のため別 ADR で検討。

影響 (Consequences)

§5.1 正の影響 (Good)

  • 6.7 分の待機中に中間結果が見える
  • Gate1 盲点・Gate2 CONFLICT を早期把握し中断・方針修正できる
  • 既存基盤の延長で ~2.0 人日で実装可能
  • feature flag で即時ロールバック可能

§5.2 負の影響 (Bad)

  • DO write +~7/セッション・storage 増(≤64KB/session で抑制)
  • 中間↔最終の差を起案者が混乱する可能性(暫定バッジで緩和)
  • 早期 CONFLICT 表示で誤った中断(false negative)が増える恐れ(盲点 #5、#11)
  • 8KB 切り詰めにより partial と最終 result の内容差が拡大し認知的不整合を生む(盲点 #4、#7)
  • 暫定結果が社外共有された場合に意思決定記録の信頼性を毀損する恐れ(盲点 #10)
  • 2 人日見積もりがアクセシビリティ・モバイル・エラー組合せテストを含まずスコープクリープの恐れ(盲点 #12)

§5.3 中立・トレードオフ (Neutral / Trade-offs)

  • 並列 gate 書込 race → DO 内で storage.put(gateKey, value) を key 単位独立書込にし read-modify-write を排除(盲点 #3、#6)。統合テストに人工的並列遅延を含める
  • DO サイズ上限近傍 → 8KB 切り詰めは severity 降順ソート後の先頭 N 件取得、切り詰めフラグを payload に付与、UI で「他 X 件省略」を明示(盲点 #4、#7)
  • 課金増 → Cloudflare Dashboard で DO write 数・storage を監視、+20% 超でアラート発火(盲点 #6)
  • エラー時切り分け → lastSuccessfulGate + UI 表示(盲点 #8)
  • LangGraph stream event 仕様への依存 → インターフェース層として分離、現在使用バージョンを記録、アップグレード時の回帰テスト要件を明記(盲点 #2)
  • 問題定義の二重化(視認性 vs 行動変容)→ 主目標を「視認性改善」に置き、早期中断率は副次 KPI として扱う(盲点 #3、#11)
  • ポーリング間隔と複数 gate 同時到着 → partialResults 各 key に version/timestamp を持たせ、クライアント側で既描画 key との差分比較で描画(盲点 #5、#8)
  • flag OFF 時の互換性 → pollSessionpartialResults 不在時は旧描画にフォールバックする defensive code、runbook 事前文書化(盲点 #9)
  • 暫定結果の社外共有 → パネル内に「処理中の中間状態であり確定情報ではありません」の免責テキストを常時表示、監査ログは確定結果のみ記録(盲点 #10)

完了条件 (観測可能 KPI):

  • 中間描画レイテンシ: gate 完了→UI 描画まで ≤ 3 秒
  • partial 表示成功率: 描画トリガー成功 / 全 partial 到着 ≥ 99%
  • 早期中断率の前後比較: 導入前ベースライン取得 → 導入後「Gate1/2 表示後の意図的中断率」を比較
  • 誤中断の質的検証: 中断後の再起案セッション数、Gate2 CONFLICT が出たが最終承認された割合を追跡
  • 統合テスト(到着順/完了整合/並列書込/サイズ上限)が CI で pass

コスト試算 (合計 ~2.0 人日):

作業工数(人日)領分
consumer: partialResults merge patch + 8KB 切り詰め + lastSuccessfulGate0.5main
chat.html: pollSession 逐次描画 + gate パネル + 暫定/確定バッジ1.0main
テスト(到着順・完了整合・並列書込 merge・DO サイズ上限近傍)0.5main

影響範囲:

対象変更内容
drp/src/do/pipeline_session.tsDO スキーマ差分: PipelineSessionStatepartialResults: Record<GateKey, object>lastSuccessfulGate: string | null を追加。patch は key 単位 merge
drp/src/queues/pipeline_consumer.ts:150/156 の stream イベントで partialResults[gate] を patch、:195 周辺のエラー時に lastSuccessfulGate を記録
drp/public/chat.htmlpollSession(:2581 付近)で partialResults 逐次描画、gate 別パネル + 暫定/確定バッジ、エラー時「Gate X まで完了/Gate Y 失敗」表示
feature flagPROGRESSIVE_GATE_RESULTS(env var or KV)。既定 OFF→検証後 ON
関係者起案者=代表取締役 / レビュー=代表取締役 / 利用者=全起案者(将来 Jr)

partialResults データ構造例:

{ "socratic": {"findings":[{"title":"...","severity":"high"}]},
  "consistency": {"verdict":"INFO"},
  "parallel_review": {"summary":"...(≤8KB 切り詰め)"},
  "scoring": {"total":41,"pass":true} }

各 gate 値は ≤8KB に切り詰め、session 合計 ≤64KB(DO 128KB/value 上限内)。

コスト試算 (Cost Estimate)

Corrigendum (2026-05-30): 本 § は cost-estimation-section lint (ADR-0088) 準拠のための構造補正 (ADR-0031 immutable + corrigendum パターン)。コスト内訳は §影響 内の「コスト試算 (合計 ~2.0 人日)」表 (本文 immutable) に既出で、ここでは要約のみ再掲する。

  • 合計 ~2.0 人日: consumer patch 0.5 + chat.html 逐次描画 1.0 + テスト 0.5 (いずれも main 領分)。詳細表は §影響 を参照。

長期影響 / Review After

  • Review After: 2026-08-29 (導入 3 ヶ月後) / 2027-02-28 (1 年内の恒久化判断)。4 週レビュー(撤退条件)とは別に、半年〜1 年スパンで以下を点検:
    • feature flag の恒久化判断: 6 ヶ月時点で KPI(早期中断率改善・partial 表示成功率 ≥99%)を満たせば flag を撤去し常時 ON 化、満たさなければ撤去(コード削除)。flag を「暫定」のまま放置しない。
    • SSE/WebSocket(案 C)への発展経路: ポーリング+partial で複数 gate 同時到着の体験劣化(盲点 #5)が顕在化、または起案頻度増でポーリング負荷が問題化した場合、本 ADR を前提に SSE 移行 ADR を起案。本実装の partialResults スキーマは SSE 化時も再利用できる形にする。
    • LangGraph stream 仕様変更の保守負債: @langchain/langgraph のメジャー更新で stream イベント仕様(node 名・stream_mode)が変わると partial patch 機構が黙って壊れる(盲点 #2)。stream 依存をインターフェース層に分離し、更新時の回帰テストを必須化。半年ごとに upstream changelog を確認。

撤退条件 (Rollback Plan)

  • 導入後 4 週で、partial 描画がトリガーされたセッションのうち Gate1/2 表示後の早期中断が 5% 未満 → 体感改善に寄与せずと判定し feature flag OFF(最終一括表示へ)
  • DO write が想定(+7/session)の 2 倍超 が常態 / session storage が 64KB 常時超過 → 要約仕様見直し or flag OFF
  • Cloudflare Dashboard で DO write 数・storage・課金が導入前比 +20% 超 → アラート発火・即時 flag OFF・原因調査
  • 誤中断(承認されるべき起案の早期廃棄)が再起案ログで増加 → CONFLICT パネルの文脈説明強化 or flag OFF
  • Gate2 CONFLICT 表示後の最終承認率が導入前比で 20% 以上低下 → flag OFF(盲点 #11)
  • 手順: PROGRESSIVE_GATE_RESULTS を OFF にするだけで既存挙動へ即時復帰。pollSession の defensive fallback により in-flight session も互換維持(盲点 #9)。判定は 4 週レビュー(担当: 代表取締役、カレンダー事前登録)

Confirmation

  • 検証手段: (1) 統合テスト(到着順/完了整合/並列書込/DO サイズ上限近傍)を CI に追加し Gate 2 で pass を必須化、(2) Cloudflare Dashboard で DO write 数・storage・課金を週次モニタリング、(3) ADR-0087 telemetry に partial 描画イベント・中断イベントを記録し週次集計、(4) 4 週後の手動 QA レビューで早期中断率・誤中断率・最終承認率を比較
  • 実行頻度: CI(PR 毎)、Dashboard モニタリング(週次)、telemetry 集計(週次)、レビュー(4 週後)
  • 違反時対応: KPI 未達 or 撤退条件抵触時に PROGRESSIVE_GATE_RESULTS を即時 OFF、原因調査の Issue を起票

実装後 corrigendum (2026-05-30): 既知の限界 — pre-graph gate (triage/socratic) 未カバー

本 ADR は immutable。本節は ADR-0031 corrigendum 方式による実装後の追記で、決定本文は変更しない。

  • 症状: chat UI で要否判定が確定 (例: Standard) しても、「審査中の中間結果」パネルが triage判定: - / モード: - のまま。
  • 原因: triage / socraticsrc/queues/pipeline_consumer.tspreGraph.invoke() (非ストリーミング) で実行され、per-gate の patchPartial は streaming ループの on_chain_end でしか発火しないため、partialResults.triage / partialResults.socratic が書き込まれない。逐次表示の対象は streamed main graph の gate のみで pre-graph gate は対象外という設計上の抜け。
  • 影響: Implementation Status: Done は main graph 系 gate (consistency 以降) に対するもの。triage/socratic の中間表示は未達。
  • follow-up: 修正方針・デプロイ確認を [[main_2026-05-30_bug_adr0089-partial-triage-gap]] (sub→main 申送り) に記載。main 領分で patchPartial('triage'/'socratic', ...) を pre-graph 経路に追加して解消予定。解消時に本 corrigendum を更新する。

解消 (2026-06-04, DRP-378): socratic は ADR-0071 で main graph へ移動済みのため streaming で捕捉される (現存ギャップは triage のみ)。pipeline_consumer.ts の pre 解決点で patchPartial('triage', extractGatePartial('triage', pre)) を明示書込して解消。あわせて main graph の triage ノードが skip 時に返す空出力 {} が正値を上書きしないよう、extractGatePartial('triage', ...)needsAdr 不在の出力で null を返す (patchPartial スキップ)。

参照 (References)

  • 関連 ADR:
    • ADR-0066(非同期 Queues + Durable Object): 本機能は DO セッション状態に partialResults/lastSuccessfulGate を追加する拡張。0066 の async/DO 設計が前提
    • ADR-0087(telemetry gate_timings 構造化): per-gate 所要時間計測済。逐次表示はその UX 版。partial 描画/中断イベントも telemetry に記録
    • ADR-0071(盲点検出を情報提供型に再定義): 早期に盲点を見せる本機能は「情報提供」意図と整合
    • ADR-0088(コスト試算必須化): 本起案もコスト試算を内包(dogfood)
  • 関連 PR/Issue: PR #1148 (起案 auto-PR / Accepted 化キュレーション)、PR #1160 (PR-1 DO partialResults + per-gate patch、flag OFF)、PR #1162 (PR-2 chat UI 逐次描画パネル + 暫定バッジ)、PR #1164 (PR-3 flag ON + smoke test 手順)、PR #1166 (## コスト試算 H2 化 corrigendum)
  • 外部資料: LangGraph stream イベント仕様。現在使用バージョン @langchain/langgraph ^1.3.0(drp/package.json)。stream_mode/node 名仕様への依存はインターフェース層に分離し、メジャー更新時に回帰テストを実施する。

11. 参照: Pipeline 審査履歴 (2026-05-29 実行時, 通常 flow)

Decision Pipeline で本草案を通常 flow (retroactive=false) で審査した結果。Gate4 45/50 (Standard 閾値 40 + 5pt 余裕、Critical 45 も到達) + Cross-Validation/Consistency/Policy Alignment すべて INFO/Proceed。impact/rollback/completion を数値化した再投入で 39→45 に改善した適用例。

📋 Pipeline 審査履歴 全 Gate 結果 (合格 Score 45 / 50) — クリックで展開

Gate 0-4 結果

  • Gate 0 Triage: needsAdr=true / triageMode=Standard
  • Gate 1 Socratic: 盲点 12 件検出 (情報提供型、§5.2/§5.3 に反映)
  • Gate 2 Consistency: INFO (ADR-0066/0087/0071/0088 と整合、矛盾なし)
  • Gate 3 Parallel Review: 3 vendor (Gemini/Claude/o3) の指摘を §5.3・撤退条件・長期影響へ反映
  • Cross-Validation / Policy Alignment: INFO / Proceed (Must 軸毀損なし、監査トレーサビリティ・Reversibility 高水準)
  • Gate 4 Scoring: 45 / 50 (scoringMean 45.4, stdDev 0.5)
#採点項目点数
1問題定義5
2代替案4
3判断基準5
4過去 ADR 整合性5
5影響範囲5
6運用上の罠5
7ロールバック性5
8コスト試算4
9完了条件4
10長期影響3

合計: 45 / 50

Status 遷移

  • 本 PR で Status: Proposed → Accepted。採点時の最弱項目(§10 長期影響)を補強:
    • Scope: platform 追加 (ADR-0049 / adr-lint scope-meta 解消)
    • §長期影響/Review After 新設 (3ヶ月/1年の恒久化判断・SSE 案C 発展経路・LangGraph 仕様変更保守負債)
    • LangGraph version の未記載を ^1.3.0 で充足