型付き辺: 出 4 / 入 0
ADR-0158: コストゲートを triage から独立ノードへ分離し ABC スクリーンの後段に置く
- Status: Accepted
- Mode: Standard
- Kruchten Type: Executive/Property
- Scope: platform
- Implementation Status: Done (drp #2152 同梱実装・worker v c2d51b1a 本番反映 2026-06-18・撤退条件監視 4週)
- 起案者: [email protected]
- 起案日時 (JST): 2026-06-18 20:19
- 承認日時 (JST): 2026-06-18 22:47 (Pipeline 通常 flow Standard 44/50 通過 + Cross-Validation 却下なし・Consistency INFO、PR #2147 マージ)
- Approver Role: platform
- Approver Who: [email protected]
- Driver: [email protected]
- Consulted: Decision Pipeline AI 審査 (Gate 0-4)
コンテキスト
§1.1 背景
ADR-0157(ABC 守りの価値スクリーン)は、不可逆 harm(A)を受付で検出し審査深度を Critical へ強制する設計を採用した。同 ADR の §検討した代替案 案5 で「Critical 級の変更」として ADR-B(本 ADR)へ送り先付きで分離されていた、コストゲートと ABC スクリーンの順序整合性問題を解決する。
§1.2 現状 (As-Is)
ABC スクリーン(abc_screen)は triage の 後段に置かれる一方、ADR-0088 のコストゲートは triage ノードの 内部(drp/src/nodes/triage.ts:347-366)で動く。コスト試算が無い Standard/Critical 起案はこのコストゲートで rejected=true となり、グラフは END へ分岐する(drp/src/graph.ts:51-53)。
§1.3 課題
コスト試算を書かずに出された不可逆 harm(A)の起案は、abc_screen に届く前に triage で却下される。ABC スクリーンは下流にあるため、すでに END へ抜けた run を呼び戻して A を ROI 免除することが構造上できない。これは ADR-0157 の K.O. 軸 #safe(不可逆 harm A を取りこぼさない)に対する設計上の穴である。
定量: 現状コストゲートは triage 内・mode 決定直後の 1 箇所(triage.ts:347-366)。A 相当でコスト未記載の却下は ABC スクリーン未到達で telemetry に abc_verdict が残らない(= 取りこぼしが観測量にすらならない)。
§1.4 制約・要件
abc_screenの verdict(abcVerdict)に依存するため、ADR-0157 の実装と整合させる。- 非 A 経路(B/C/Confidence/INVALID/null)のコストゲート挙動(却下メッセージ・reason code・
triageRejectKind)を一字一句維持する(外形挙動を変えない)。 cost_gateノードは LLM を呼ばない純コード判定とし、Workers subrequest と LLM コストを増やさない。- ADR-0120 の GATE_KEYS / interruptAfter 順序契約を更新する。
- env フラグで緊急停止できる(
PREGATE_ENABLEDと同型)。
§1.5 目標 (To-Be)
不可逆 harm A の取りこぼしを構造的に塞ぎ(#safe)、コストゲートの判定根拠(abc_verdict)を観測可能にする(#reliable)。Non-Goals: コストゲートの検査内容(コスト試算の有無)の変更、Light 起案の扱いの変更、ABC スクリーン自体の責務変更。
決定
ADR-0088 コストゲートを triage から cost_gate ノードへ逐語抽出し、triage → abc_screen → cost_gate → pregate の順に配置する。abcVerdict==='A' はコスト未記載でも rejected させず「コスト試算 推奨」note を付けて通過(A 免除、cost_gate_verdict='A_AWARE_PASS')。非 A(B/C/Confidence/INVALID/null)はコスト未記載で従来どおり却下し、メッセージ・reason code・triageRejectKind を逐語維持する。cost_gate は LLM を呼ばない純コード判定とし、triage から hasCostEstimate 等の判定ヘルパを逐語移送する。Light は従来どおり免除。
判断基準 (Decision Drivers)
3.1 評価軸
| # | 軸 | 重要度 (係数) | 案件特有の解釈 |
|---|---|---|---|
| 1 | #safe | [Must] (×2.0) | コスト未記載の不可逆 harm A を受付で取りこぼさない (K.O.) |
| 2 | #reliable | [Must] (×2.0) | 非 A 経路のコストゲート挙動を一字一句維持し、A 免除を cost_gate_verdict で観測可能にする |
| 3 | #operable | [High] (×1.0) | COST_GATE_ENABLED env フラグで即時に素通し・緊急停止できる |
| 4 | #maintainable | [Medium] (×0.5) | 判定はプロンプトでなくコードに置き、triage の責務を 1 つ減らす |
K.O. criterion: #safe score < 3 は不採用(A を却下するなら本案は無意味)。
3.2 評価軸 × 案スコア表
| 軸 | 係数 | 採択案 (cost_gate 分離) | 案 1 (triage 内 A-aware) | 案 2 (ABC を triage 内へ) | 案 3 (何もしない) |
|---|---|---|---|---|---|
#safe | ×2.0 | 5 | 3 | 4 | 1 |
#reliable | ×2.0 | 5 | 2 | 3 | 3 |
#operable | ×1.0 | 5 | 4 | 3 | 5 |
#maintainable | ×0.5 | 4 | 2 | 2 | 3 |
| 加重和 (正規化) | 0.967 | 0.567 | 0.667 | 0.567 | |
| K.O. 通過 (Must ≥3) | ✓ | ✓ (#safe=3 ぎりぎり) | ✓ | ❌ (#safe=1) |
検討した代替案 (Alternatives Considered)
- 案 1: triage 内のコストゲート条件を A-aware にする — triage は ABC 分類より前に動くため、コストゲート時点で A か分からない。triage 内に安価な A シグナル(キーワード照合)を持つと、ADR-0157 が確立した「LLM=意味分類 / コード=照合+routing(キーワード表でない)」の再現性アーキを二重化・劣化させる。不採用。
- 案 2: ABC スクリーンをコストゲートより前(triage 内)へ移す — triage 順序の全面再設計で、LLM 呼び出しを triage 内へ持ち込む最も大きな変更。
abc_screenを独立ノードに保つ ADR-0157 の決定と矛盾する。不採用。 - 案 3: 何もしない(ADR-0157 の §案5 撤退トリガーに委ねる) — ADR-0157 は「ADR-B 未着手なら force-Critical を env 無効化」を送り先付きで明記しており、その送り先(本 ADR)を起こさないと #safe の穴が恒久化する。期限(本番反映後 4 週)内に着手する義務がある。不採用。
- 案 4(盲点 #3 由来): cost_gate を ADR-0157 PR から分離して独立 PR にする — abc_screen 不具合 revert 時に cost_gate を生かす選択肢。本決定では「同梱+triage 旧コード段階削除」で対応するが、運用上の選択肢として記録(§5.3 参照)。
影響 (Consequences)
§5.1 正の影響 (Good)
- コスト未記載の不可逆 harm A を受付で取りこぼさなくなる(
#safeの穴を構造的に塞ぐ)。 - triage の責務が 1 つ減る(コストゲート分離)。
- コストゲートの判定根拠が
cost_gate_verdictとして telemetry に残り、A 免除率を観測可能になる。
§5.2 負の影響 (Bad)
- パイプラインのゲートが 1 増える(
abc_screenと合わせ 11→13)。 - ADR-0120 の GATE_KEYS / interruptAfter 順序契約の更新箇所が増える。
- 非 A 経路の逐語維持のため golden/snapshot test が増え、将来のメッセージ改善時に snapshot 更新コストが発生する(盲点 #7)。
§5.3 中立・トレードオフ (Neutral / Trade-offs)
- telemetry に
cost_gate_verdict列を 1 つ追加する。 - LLM 呼び出しは増えない(
cost_gateは純コード判定)。 - abc_screen 障害時の fallback(盲点 #1):
abcVerdictがnull/'INVALID'/ 予期しない値のとき、cost_gateはtriageMode==='Critical'なら通過させて構造化アラートを上げる(silent BLOCK を避ける)、それ以外は非 A 扱いで従来 BLOCK。fallback 経路を unit test の網羅対象とする。 - migration 順序(盲点 #2):
cost_gate_verdict列の migration を独立した先行デプロイ PR に切り出し、ABC スクリーン PR / cost_gate PR の両方の前提条件として merge 順序をデプロイ手順書に明記する。Cloudflare D1 の schema-on-write 列欠損は例外になるため、列追加は merge 前に remote へ先行適用する。 - 同梱 PR の revert 戦略(盲点 #3): ADR-0157 PR と同梱するが、triage 内の旧コストゲートコード(
triage.ts:347-366)は本 PR 時点では削除せず、後続 PR で「cost_gate安定稼働 2 週間 + revert 期限 4 週超過」の両条件を満たした時点で削除する(段階削除)。これにより abc_screen / cost_gate を同梱 revert しても triage 側でコストゲートが残る。 - GATE_KEYS 配線検証(盲点 #4): graph.ts の GATE_KEYS 要素数・順序を assert する integration test を追加し、
cost_gate_verdictが記録されていない run を週次 telemetry で異常検知する。 - A verdict 値の将来拡張(盲点 #6):
cost_gateの A 免除条件をabcVerdict==='A'の文字列リテラル直接比較ではなく、abc_screenが export するisAVerdict()ヘルパ(またはAbcVerdictunion 型)で参照する。ABC スクリーンの verdict 拡張時に cost_gate の修正が型チェックで自動検知される。
撤退条件 (Rollback Plan)
- env フラグ
COST_GATE_ENABLED=falseでcost_gateノードを即時素通し(PREGATE_ENABLEDと同型の緊急停止)。 - A 免除の悪用監視:
cost_gate_verdict='A_AWARE_PASS'(A 相当でコスト未記載のまま通過)の率が、デプロイ後 telemetry 安定 2 週間を起算点として、週次 A 起案数 5 件以上の週で 4 週連続 50% 超となったら A 免除を無効化(非 A 同様に BLOCK へ戻す)。途中 1 週でも閾値を割ったらカウントリセットだが、絶対件数の補助閾値として「A 免除通過 累計 20 件 到達」または「前月比 200% 増」のいずれかに該当した時点で即時レビュー(4 週待たない)。週次 5 件未満の週は判定スキップ(標本不足)。 - ABC スクリーン未稼働時(
ABC_SCREEN_ENABLED=false)はabcVerdict='PASS'で A 免除が発火せず、全 Standard/Critical がコストゲート対象に戻る(安全側 degrade、設計意図どおり)。 abc_screenLLM 障害でabcVerdict=null/'INVALID'が継続発生した場合、Critical 起案は fallback 経路で通過しアラートで人手介入を促す(§5.3 参照)。
コスト試算
- 実装: 約 0.5〜1 人日(triage からのコストゲート逐語抽出 +
cost_gate.ts純ノード + graph 配線 + telemetry 列 + unit test + integration test + abc_screen verdict 型共有化)。ADR-0157(abc_screen)実装 PR と同梱(abcVerdict依存のため)。 - migration:
cost_gate_verdict列追加の独立先行 PR が +0.25 人日。 - 運用 / LLM:
cost_gateは LLM を呼ばない純コード判定のため LLM 増分コストはゼロ。Workers subrequest も増えない。 - 将来コスト: snapshot test の保守コストとして、ユーザー向けメッセージ改善時に regex 化へ切り替える追加 0.25 人日を見込む(Confirmation 参照)。
Confirmation
- 検証手段:
cost_gate.tsの unit test: A→A_AWARE_PASS(rejected せず)/ 非 A のコスト未記載→BLOCK(rejected・メッセージ/reason code 不変)/ Light→免除 / コスト試算あり→PASS /abcVerdict=null|'INVALID'|未知値+triageMode='Critical'→通過+アラート / 同+非 Critical→BLOCK(盲点 #1)。- 非 A 経路の reason code と
triageRejectKindの enum 値 を golden test で固定(値の完全一致)。ユーザー向けメッセージ文字列は正規表現マッチで検証し、将来のユーザビリティ改善・多言語対応を妨げない(盲点 #7)。 - graph.ts の GATE_KEYS 要素数・順序を assert する integration test(盲点 #4)。
abc_screenverdict 型(AbcVerdictunion /isAVerdict()ヘルパ)を共有 import し、型チェックで A verdict 値拡張を自動検知(盲点 #6)。
- 実行頻度: unit / integration / golden test は PR ごと(pre-push)。
cost_gate_verdict分布・A 免除率・cost_gate_verdict欠損 run 数は週次 telemetry レビュー。 - 違反時対応:
- 非 A 経路の reason code /
triageRejectKinddrift → PR ブロック、逐語移送を修復。 - メッセージ regex 不一致 → PR ブロック、意図的変更なら regex を更新。
- GATE_KEYS assertion 失敗 → PR ブロック、配線修復。
cost_gate_verdict欠損 run 検出 → on-call 即時調査(配線消失の無音障害検知)。- A 免除率が撤退閾値超過 → A 免除を無効化(撤退条件)。
- 非 A 経路の reason code /
- KPI: 非 A 経路の reason code /
triageRejectKindgolden 一致率 100%、cost_gate_verdict欠損率 0%(週次)、A 免除率 50% 未満(週次・標本 5 件以上の週)。
参照 (References)
- 関連 ADR:
- ADR-0157: ABC 守りの価値スクリーン — 補完/前提(本案は ADR-0157 の §案5 送り先を充足し、
abcVerdict==='A'を読んで A を ROI 免除する。ADR-0157 実装 PR と同梱) - ADR-0088: コスト試算必須化 — 改定/移設(コストゲートの配置を triage 内から独立ノードへ移す。検査内容・非 A の却下挙動は不変)
- ADR-0130: スコープ外前提の送り先パターン — 適用(ADR-0157 が本 ADR を送り先として起票義務+期限 4 週+撤退トリガー付きで分離した、その受け皿)
- ADR-0142: 問題空間切り分けプリゲート — 並立(同じ受付バンドの別検査。本案はコストゲートの配置のみ触る)
- ADR-0102: 審査深度の階層化 — 並立(Light 免除の扱いを維持)
- ADR-0120: GATE_KEYS / interruptAfter 順序契約 — 更新(ノード追加で順序契約を改定)
- ADR-0157: ABC 守りの価値スクリーン — 補完/前提(本案は ADR-0157 の §案5 送り先を充足し、
- 関連 PR/Issue: -
- 外部資料: -
11. 参照: Pipeline 審査履歴
Decision Pipeline (Gate 0-4) 審査結果 — 起案 PR #2147 (2026-06-18 マージ)
Gate 0 (Triage)
needs_adr: Yes / Mode: Standard。ADR-0157 の §検討した代替案 案5 が予定した送り先 (コストゲートの A-aware 化) として ADR-0130 パターンで起票。
Gate 1 (Socratic — 盲点検出と本文補強)
Must 軸に対する盲点 7 件を検出。本文生成が起案者の生テキスト外で織り込んだ補強策を Pipeline 補強一覧として提示し、起案者 (= 承認者) が全件を承認 (CI adr-reinforcement-checklist 通過):
- abc_screen 障害時の fallback (
abcVerdict=null/'INVALID'/未知値+triageMode='Critical'で通過+アラート / 同+非 Critical で BLOCK・盲点 #1) - migration の独立先行 PR 化と merge 順序のデプロイ手順書明記 (盲点 #2)
- triage 旧コストゲートコードの段階削除戦略 (
cost_gate安定 2 週 + revert 期限 4 週超過の両条件・盲点 #3) - GATE_KEYS 配線 assert +
cost_gate_verdict欠損 run 検出 (盲点 #4) - 撤退閾値の起算点・標本数・累計 20 件 / 前月比 200% 補助閾値による即時レビュー (盲点 #5)
isAVerdict()ヘルパ /AbcVerdictunion 型での verdict 拡張自動検知 (盲点 #6)- 非 A 経路の reason code /
triageRejectKindenum を golden 固定・メッセージは regex マッチ (盲点 #7)
Gate 2 (整合性チェック)
判定: INFO (PASS 相当だが複数の補完・改定関係あり)。ADR-0157 の §案5 送り先として明示的に起票され、ADR-0088 のコストゲート決定を 配置のみ改定/移設(検査内容・非 A 経路の挙動は逐語維持)するため CONFLICT/SUPERSEDE に該当せず。ADR-0120 (GATE_KEYS 順序契約) はノード追加に伴う更新が前提・本文 §1.4 で明記。ADR-0102 (Light 免除) / ADR-0142 (プリゲート並立) と矛盾なし。
Gate 4 (スコアリング) — 44 / 50 (Standard 閾値 40 を通過・PASS)
| 項目 | スコア | 要旨 |
|---|---|---|
| 1_problem_definition | 4/5 | ファイル/行番号・課題の構造的説明は具体。実際の取りこぼし頻度・規模の推定値が欠落 (観測不能だからこそ間接指標が欲しい) |
| 2_alternatives | 5/5 | 案 1〜4 + 盲点由来案まで網羅、各却下理由が技術的に明快 |
| 3_decision_criteria | 5/5 | 評価軸 × 案スコア表 + 係数 + 加重和 + K.O. 通過判定まで完備 |
| 4_past_adr_consistency | 3/5 | 本文では ADR-0088「改定/移設」ADR-0157「補完/前提」ADR-0120「更新」と関係明記、frontmatter の amends/refines/depends_on/relates_to が空 (受理時に Policy Alignment 推奨に従い amends: [ADR-0088, ADR-0120]・depends_on: [ADR-0157]・refines: [ADR-0130] を populate 予定 = 下記 Status 遷移参照) |
| 5_impact_scope | 4/5 | ファイル/列追加/env フラグは特定済。新規 cost_gate.ts の配置 dir やステークホルダー (on-call/起案者以外) の明示がやや弱い |
| 6_operational_pitfalls | 5/5 | 盲点 #1〜#7 を列挙し各対策まで設計済、cost_gate_verdict 欠損 run 検出も配線消失の無音障害として監視 |
| 7_rollback_strategy | 5/5 | env フラグ即時停止、A 免除悪用監視の閾値が「4 週連続 50% 超 OR 累計 20 件 OR 前月比 200%」と多層、ABC 停止時の degrade 挙動も明示 |
| 8_cost_estimate | 5/5 | 実装 0.5〜1 人日 / migration +0.25 人日 / LLM 増分ゼロ / snapshot 保守 +0.25 人日と数値明示 |
| 9_completion_criteria | 5/5 | unit/golden/integration/週次 telemetry の観測可能な KPI (一致率 100%・欠損率 0%・A 免除率 50% 未満) が明確 |
| 10_long_term_impact | 3/5 | snapshot 保守コストとノード数増 (11→13) は触れている、Review After 日付が無く半年後の負債化リスクの評価が薄い |
| 合計 | 44/50 | Standard 閾値 40/50 をクリア (PASS) |
Cross-Validation (Blind-spot × Must)
| 評価軸 | スコア | 盲点毀損 |
|---|---|---|
| #safe | 5 | 7 件 (critical 2 / high 3 / medium 2) — 全 OK |
| #reliable | 5 | 7 件 (critical 2 / high 3 / medium 2) — 全 OK |
| #operable | 5 | 7 件 (critical 2 / high 3 / medium 2) — 全 OK |
| #maintainable | 4 | 7 件 (critical 2 / high 3 / medium 2) — 全 OK |
最終 verdict: Accept (rejected:false。body-only mitigation を ADR-0150 例外として認める。本文 §5.3 と Confirmation が盲点に対する fallback・段階削除・integration test・補助閾値・型共有・regex マッチ等を起案者の生テキスト外で織り込み、CV がそれを正当な根拠と認めた)。
3 モデル評価 (Gemini / Claude / o3)
- 強み: abc_screen 障害時の fallback 経路、段階削除による revert 戦略、env フラグ即時停止、定量 KPI ロールバック条件、
isAVerdict()型共有。 - 懸念 (共通): pregate と abc_screen の配置順 (pregate を先に置けば LLM コスト節約という指摘) / 撤退条件の運用複雑性 (多段閾値の認知負荷) / 0.5〜1 人日の見積過少 /
COST_GATE_ENABLED=false緊急停止時の ADR-0088 検査消滅 / 旧コストゲート残存による二重判定リスク / ローリングデプロイ中のノード順序混在 / 列追加の前方互換ない期間 / LLM 誤分類で A→非 A 判定された場合の取りこぼし。
Policy Alignment (自社方針適合)
総合判定: ✅ 方針整合 (指摘事項あり)。ADR-010 整合性 / 監査要件 / 1 人法人コスト / 既存メモリ整合 / Jr 受け入れ / Reversibility の 6 軸すべて整合。非受容リスク抵触なし、技術制約抵触なし。受容リスクは snapshot 保守コスト (regex 化で回収可能)、A 免除悪用 (週次閾値で検知)、GATE_KEYS 順序契約更新 (CI assertion で検知)。推奨アクション: ① frontmatter の typed edges (amends: [ADR-0088, ADR-0120] / depends_on: [ADR-0157] / refines: [ADR-0130]) を埋める、② Confirmation を Jr 引き継ぎドキュメントの必読項目に登録、③ 週次 telemetry レビュー項目を四半期レビュー定例に組み込む。
Status 遷移 (Proposed → Accepted)
- 起案時の最低評価は軸 4 (過去 ADR 整合性 3/5) と軸 10 (長期影響 3/5)。軸 4 の typed edges は受理 PR で
amends: [ADR-0088, ADR-0120]・depends_on: [ADR-0157]を populate し、相手側の双方向辺 (amended_by/depended_on_by) も同 PR で更新する (adr-lint.mjs --check-edges整合)。本文の参照節が言及する「ADR-0130: スコープ外前提の送り先パターン」は実体 ADR-0130 のタイトル (automate-index-toc-catalog-generation) と一致しない誤参照のため、本受理 PR では typed edge への populate を見送る (本文修正は別 PR で実施)。 - 軸 10 の Review After は本案の telemetry 安定 2 週 + A 免除率 4 週判定が一巡する 2026-09 月初 を目安に運用見直しレビューを実施する。
- Gemini / Claude / o3 が指摘した「撤退条件の運用複雑性」「
COST_GATE_ENABLED=false時の ADR-0088 検査消滅」「LLM 誤分類で A→非 A 判定」は、本受理時点では env フラグ即時停止と週次 telemetry レビューでカバーする (将来の運用観察で必要なら別 ADR で改善)。 - 起案者 (= 承認者) が CV 全 OK + Policy Alignment 整合 + 補強一覧全項目承認をもって Accepted とした (2026-06-18 22:47 JST、PR #2147 マージ)。
- 副作用注記 (diff 自己レビューで確定した medium・本受理の意図的帰結): 本決定によりコストゲートを triage から独立ノードへ移すことで、cost-missing かつ ADR-0091 違反を同時に持つ Standard/Critical 起案の reject reason_code が 旧 (cost-missing 優先) → 新 (triage 内の ADR-0091 が先発火) に変わる。両者とも pre-gate-block で差し戻すためユーザー体験・情報損失は無く、本 ADR の意図する責務分離 (cost ゲートを後段へ移す) の帰結である。telemetry の reason_code 帰属が overlap 集合 (両違反同時) でこの境目で切り替わる ため、移行前後の reason_code 分布を 4 週間並列観測する。