TL;DR(このノードは何をする・専門語ゼロ): 採点で高得点が付いた下書きでも、「中身が本当に裏付けされているか」までは点数に出ない。このノードは、前段が見つけた見落としの一覧と、本文が「これは絶対外せない」と位置づけた評価項目を一つずつ突き合わせ、その見落としが高評価の土台を崩していないかを照合する。土台を崩す重大な組み合わせが見つかった時だけ差し戻し、それ以外は記録だけ残して次へ進める。

実装: drp/src/nodes/cross_validation.ts プロンプト: KV ID cross-validation (ADR-0085 で KV lifecycle 管理対象。ノード内 FALLBACK_PROMPT をフォールバック) LLM パラメータ: KV ID gate2-consistency の params を流用 (temperature 0.2 / seed 42) 位置づけ: Gate 4 Scoring の後段、Gate 2 Consistency の前段 (graph.ts: scoring → cross_validation → consistency) テスト: なし (差戻し semantics は ADR-0076 / ADR-0092 の retroactive validation で検証)


1. 役割と位置づけ

Gate 4 Scoring は ADR 文面の品質 (10 項目 × 5 点) を評価するが、「記述内容が検証済みか」は問わない。 文面が巧みでも技術的前提が未検証なら高得点が付き得る。本ノードはこのギャップを埋める。

  • 解決する課題: Gate 1 (盲点検出エンジン / ADR-0071) が挙げた blind-spot findings〔blind-spot=盲点。採点の土台を崩しうる未検証の前提や見落とし〕と、本文 §3.1/§3.2 の Must 評価軸〔Must 軸=この決定で絶対に外せない必須評価軸〕スコアを突き合わせ、「ある盲点が、ある Must 軸の高スコアを正当化する前提を毀損 (undermines) していないか」を検証する。
  • 設計思想: Scoring (文面品質) と Cross-Validation〔Cross-Validation=交差検証。盲点が採点の前提を崩さないかの照合〕 (内容の検証済み度) の役割分離。 「文面は高品質だが技術的前提が薄い」ドラフトを的確に弾く (lessons_learned.md 参照)。
  • 由来: ADR-0076 (Gate 4 後の新ゲートとして新設) / ADR-0092 (採点安定性の可視化と整合)。

Gate 4 と本ノードは相補的。本系列で初めて両方を一度に通過した適用例は ADR-0088 (Gate4 41/50 + Cross-Validation INFO)。


2. フロー図

flowchart LR
    SC[scoring] -->|rejected=false| CV[cross_validation]
    CV -->|critical×Must×undermines| E[END 差戻し]
    CV -->|それ以外| CO[consistency]

3. トリガー条件

条件挙動
scoring を通過 (rejected=false) して遷移実行
blindSpotFindings が 0 件スキップ (検証対象なし、crossValidationVerdicts: [] で通過)
本文から評価軸 (§3.1/§3.2) を抽出できないスキップ (cross_validation_skip ログ、通過)

差戻しなしで通過した場合も crossValidationDetail / crossValidationVerdicts は生成され、PR 本文・telemetry に残る。


4. 入力 (State)

State フィールド用途
blindSpotFindingsGate 1 が出力した盲点 findings (title / severity / evidence)。検証対象の一方
adrBody本文。§3.1 から評価軸名と [Must] 重要度、§3.2 スコア表から各軸スコアを抽出

評価軸の抽出ロジック (extractEvaluationAxes):

  • §3.1: #tag を含む行から軸名を収集し、同一行に [Must] があれば Must 軸とマーク。
  • §3.2「評価軸 × 案 スコア」表から各軸のスコア (整数) を取得。

全 finding × 全 axis の直積ペアを生成 (拡張版: 全 severity / 全 importance を対象、ADR-0086 で telemetry 構造化)。


5. 処理ロジック

1. findings = state.blindSpotFindings  (0 件なら即スキップ通過)
2. axes = extractEvaluationAxes(state.adrBody)  (0 件なら即スキップ通過)
3. pairs = findings × axes の直積  (各ペア: finding_title/severity/evidence × must_axis/must_score/is_must_axis)
4. params = loadLlmParams('gate2-consistency', { temperature: 0.2, seed: 42 })
5. llm = createLlm(MODELS.consistency='claude-opus', temperature, seed)
6. prompt = loadPrompt('cross-validation', FALLBACK_PROMPT)
7. user msg: pairs (JSON) + ADR Body (context)
8. invoke → JSON 抽出 → verdicts[] (finding × axis ごとに undermines: boolean + reasoning)
9. 差戻し判定 = verdicts.filter(severity==='critical' && isMustAxis && undermines)
   - 1 件以上 → rejected=true + buildRejectionMessage
   - 0 件     → 通過 (detail のみ生成)

判定の保守性 (FALLBACK_PROMPT より): 「undermines」= 盲点が、その軸スコアを正当化するのに必要な エビデンスを直接否定する未検証前提・未テスト前提・未緩和リスクを指す。軸に関連するだけで スコア正当化を無効化しない finding は undermines としない。LLM には全 input ペアを出力させる (undermines=false 含む全マトリクスを表示・telemetry に残すため)。


6. LLM 設定

項目根拠
モデルclaude-opus (MODELS.consistency)盲点と評価軸前提の文脈理解・矛盾検出。Gate 2 と同モデルプール
temperature0.2 (KV gate2-consistency params)判定の揺らぎ最小化
seed42再現性確保 (ADR-0056 構造化 audit log)
プロンプトKV cross-validation (ADR-0085)本文 lifecycle 管理対象。フォールバックはノード内 FALLBACK_PROMPT
コストfinding 数 × axis 数のペアを 1 回の呼出で処理 (cross_validation_start ログで pairs 数を可視化)

7. 副作用

なし。LLM 呼出のみ。cross_validation_start / cross_validation_complete / cross_validation_skip / cross_validation_error の構造化ログを出力。


8. 出力 (State)

// 通過
{ crossValidationDetail: string, crossValidationVerdicts: CrossValidationVerdict[] }
// 差戻し (critical × Must × undermines が 1 件以上)
{ rejected: true, rejectionMsg: string, crossValidationDetail, crossValidationVerdicts }
  • crossValidationDetail: Must 軸を上に置いた評価軸別マトリクス Markdown (毀損は ⚠️、OK は ✅)。PR 本文に転記。
  • crossValidationVerdicts: 全ペアの判定配列。telemetry の cross_validation_verdicts 構造化カラムに格納 (ADR-0086 / ADR-0087、schema v3、PR #1134 / #1135)。
  • rejectionMsg: critical × Must × undermines のみを Must 軸別にグルーピングした差戻しメッセージ。

9. 分岐 (次ノード)

.addConditionalEdges('cross_validation', (s) => s?.rejected ? END : 'consistency')

critical × Must × undermines が 1 件以上 → rejected=trueEND (差戻し)。それ以外は consistency へ。


10. エラー時の挙動

  • LLM 失敗 / JSON parse 失敗: try-catch で fail-open〔fail-open=失敗時に止めず通過させる方針〕 (cross_validation_error ログ → crossValidationVerdicts: []通過)。
    • ⚠️ 他の reject ゲート (triage の ADR-0091 は fail-closed、policy_alignment は throw) と異なり、本ノードは 検証失敗時に通過させる 設計。「検証できなかった = 差し戻し根拠なし」と解釈する。監査上は cross_validation_error ログの有無で「検証スキップされた起案」を識別できる。
  • 盲点 0 件 / 評価軸 0 件: スキップして通過 (差戻し根拠が構成できないため)。

11. 既知の弱点・運用注意

  • 差戻しは critical × Must のみ: high/medium/low severity の盲点や非 Must 軸の毀損は 情報提供のみ (PR 本文には載るが pass/fail に不使用)。保守的に偽陽性を抑える設計。
  • fail-open のトレードオフ: LLM エラー時に素通りするため、cross_validation_error が頻発する場合は実質的にゲートが無効化される。telemetry でエラー率を監視。
  • 評価軸抽出の脆さ: §3.1 の #tag + [Must] マーカーと §3.2 スコア表の構造に依存。本文フォーマットが崩れると軸 0 件でスキップされる (Light モードは §3 省略可のため本ノードは実質スキップされやすい)。
  • コスト累積: finding 数 × axis 数のペアを claude-opus で処理。盲点が多い起案ではペア数が増える (cross_validation_start ログの pairs で把握)。
  • K-fold 安定性〔K-fold=データを K 分割して交互に検証し採点のばらつきを測る手法〕: ADR-0092 で採点安定性の可視化と整合。交差検証系列の拡張余地。

12. テストケース

なし。差戻し semantics の検証は実起案の retroactive validation で実施。

  • 適用例: ADR-0093 (v5 で Cross-Validation 差戻し Score 42/50 #reliable 毀損 → v6 で前提補強し通過)、 ADR-0095 (v2 強化版が Cross-Validation reject 48/50 → v1 シンプル版採用)。

13. 過去の設計判断ログ

日時変更経緯
ADR-0076Gate 4 後の新ゲートとして新設文面品質 (Scoring) と内容の検証済み度を分離。盲点 × Must 軸の整合を機械的に当てる
ADR-0086 / 0087telemetry に cross_validation_verdicts 構造化カラム追加 (schema v3)全 finding × axis verdict を audit に残す。PR #1134 / #1135
ADR-0092採点安定性の可視化と整合K-fold 系列との整合、軸別毀損トレンドのダッシュボード化計画
(拡張版)全 severity / 全 importance のペアを LLM に渡し、差戻しは critical × Must のみに限定表示用マトリクスは網羅、差戻しは保守的に

14. 関連リンク

  • 前ノード: 04_scoring.md
  • 次ノード: 06_consistency.md
  • 関連 ADR:
    • ADR-0071 — Gate 1 盲点検出エンジン (本ノードの入力 blindSpotFindings の出所)
    • ADR-0076 — 本ノードの新設 ADR
    • ADR-0081 — LLM resilience (maxRetries / JSON parse 堅牢化)
    • ADR-0085loadPrompt(env, 'cross-validation', FALLBACK_PROMPT) KV lifecycle 管理
    • ADR-0086 / ADR-0087 — telemetry 構造化 (schema v3)
    • ADR-0092 — 採点安定性の可視化と整合