TL;DR(このノードは何をする・専門語ゼロ): 受け取った起案が「1 つの決定」になっているかを入口でチェックする。複数の独立した決定が混ざっていたり、外へ送り出した課題の行き先が書かれていなかったら差し戻す。判定は LLM ではなくコードが下し、根拠は本文からの逐語引用と機械照合する。

実装: drp/src/nodes/problem_space_pregate.ts 判定コード (pure module): drp/src/nodes/problem_space_decide.ts プロンプト SSoT (KV デプロイ): prompts/production/gate0a-pregate-primary/prompt.mdprompts/production/gate0a-pregate-secondary/prompt.md migrate: drp/migrate-v11-pregate.sql 基盤 ADR: ADR-0142 位置づけ: triage → recall_pre_gate → abc_screen → cost_gate → problem_space_pregate → socratic 本番稼働: 2026-06-15


1. 役割と位置づけ

② 受付層は静的 4 検査だけで分析の意味検査が空白だった。本ノードは「起案が単一の決定として成立しているか」を 2 段判定で機械検査する。

  • 解決する課題: 分析が崩れた起案(複数の決定が 1 本にまとまっている・外へ送った前提の行き先がない)が、受理後の人手対話まで検出されない問題。多重却下 ADR 7 本中 7 本がこの型の盲点移動を起こしていた。
  • 設計思想: 2 段判定で受付コストを抑える。一次は軽量モデルで疑いを高再現で拾い、疑いがあるときだけ二次の構造化分解へ送る。
  • 判定の置き場所: LLM は意味分類と逐語抽出だけを担い、A/B/C 確定や塊判定はコードが下す。ADR-0142 同型の #reliable 設計。
  • 由来: ADR-0142 (Existence/Executive・Standard・2026-06-12 受理)。

2. フロー図

flowchart LR
    CG[cost_gate] -->|rejected=false| P1[一次フィルタ
gemini-flash] P1 -->|suspect=false| S[socratic] P1 -->|suspect=true| P2[二次 IBIS 分解
claude-sonnet] P2 -->|decide PASS| S P2 -->|decide INVALID| S P2 -->|decide FAIL| E[END 差戻し
pre-gate-block]

3. トリガー条件

エントリポイント起動グラフ説明
POST /draft (フォーム再送信型)buildGraphWithWebhookcost_gate 通過後に実行
POST /chat/run (チャット型・full)buildGraphwebhook を除く full pipeline

スキップ条件:

  • 既に判定済み (state.pregateVerdict != null) は冪等化で no-op。
  • env PREGATE_ENABLED=false で素通し。state は PASS を入れる。

buildPreGraph (チャット型・triage のみ) では実行されない。


4. 入力 (State)

State フィールド必須用途
titlestring任意起案タイトル
contextstring必須背景・目的の自由記述
optionsstring任意検討した代替案

プロンプトに渡す形式は triage と同形。buildPregateInput() が組み立てる。

タイトル: {title}              ← title が空なら省略

背景・目的:
{context}

検討した代替案:                  ← options が空なら省略
{options}

逐語照合は本テキスト全体を対象にする。


5. 処理ロジック

0. 冪等化: state.pregateVerdict が決定済みなら no-op
1. env PREGATE_ENABLED='false' なら素通し (PASS で state 注入)
2. 一次プロンプト (gate0a-pregate-primary) を KV から取得し gemini-flash で 1 call
   - 出力: 5 シグナル (independence_reversibility / decision_drivers / approvers /
     rollback_kpi / type_crossing) と dangling_premise_suspected を boolean+逐語引用で
   - 総合判定 suspect_multiple = いずれかが branched=true、または dangling 疑いあり
   - parse 失敗時は安全側に倒し suspect=true として二次へ送る
3. suspect=false なら PASS で終了 (LLM 1 call で完了)
4. suspect=true → 二次プロンプト (gate0a-pregate-secondary) を claude-sonnet で 1 call
   - 出力: IBIS 主張グラフ (issues / positions / arguments / premises_sent_out)
   - 各ノードに verbatim_quote 必須
   - parse 失敗は INVALID (評価不能) として通過させる
5. decide() (problem_space_decide.ts) がコードで判定
   ① 逐語引用照合: 全 verbatim_quote が本文に存在するか機械照合
      - 1 件でも不一致 → INVALID (幻覚防止・評価から隔離)
   ② root 数: is_root=true の issue が 2 以上 → FAIL (理由 root_multiple)
   ③ 行き先解決: 行き先のない premise が 1 件でもあれば FAIL (理由 dangling_premise)
   ④ いずれも該当しなければ PASS
6. FAIL → rejected=true + triageRejectKind='pre-gate-block' + 差戻しメッセージ
   PASS / INVALID → そのまま socratic へ通す

行き先の許容形 (ADR-0130 パターン): 外へ送った前提には次のどちらかが本文に要る。

  • (i) 解決を所有する既存 ADR・文書の名指し
  • (ii) 未起案なら起票義務 + 期限 + 撤退条件トリガーの 3 点明記

逐語照合の正規化: 連続空白 (改行・全角空白・タブ) を半角空白 1 個へ畳んで前後 trim する。文字そのもの (要約・言い換え) の相違は検出する厳密さを保つ。詳しい正規化は normalizeForQuoteMatch() にある。


6. LLM 設定

ノードモデルtemperature / seedコスト目安レイテンシ
一次 (primary)gemini-flash (MODELS.triage)0 / 421〜3 円/run1〜3 秒
二次 (secondary)claude-sonnet (MODELS.socratic)0 / 421〜10 円/run (二次到達時のみ)3〜10 秒
  • 一次は疑いを高再現で拾う軽量分類。二次は厳密 JSON schema での IBIS 構造化分解。
  • どちらも temperature 0・seed 42 で同一起案には同一判定。
  • プロンプトは KV-backed (loadPrompt) + ノード内 FALLBACK。FALLBACK は production の prompt.md と一字一句同じ内容を維持する。

7. 副作用

なし。LiteLLM Gateway 経由の LLM 呼出のみ。GitHub API / KV 書込 / Webhook には触れない。

構造化ログ:

  • event: 'pregate_skipped' — env OFF で素通し
  • event: 'prompt_loaded' — KV / FALLBACK の出所
  • event: 'pregate_complete' — stage / verdict / reasons / root_count / dangling_count / unmatched_count
  • event: 'pregate_primary_error' / 'pregate_secondary_error' — LLM 例外

8. 出力 (State)

PASS (分析成立)

{
  pregateVerdict: 'PASS',
  pregatePass: true,
  pregateStage: 'primary' | 'secondary',
  pregateReasons: [],
  pregateRootCount?: number,   // 二次到達時のみ
}

INVALID (評価不能・通過)

{
  pregateVerdict: 'INVALID',
  pregatePass: true,
  pregateStage: 'secondary',
  pregateReasons: [],
  pregateUnmatchedQuotes: string[],  // 本文と照合できなかった逐語引用 (先頭 5 件)
}

INVALID は per-run では止めず通過させる。撤退条件 (3 件以上で設計見直し) で集計する。

FAIL (塊混在 or 宙に浮いた前提・差戻し)

{
  pregateVerdict: 'FAIL',
  pregatePass: false,
  pregateStage: 'secondary',
  pregateReasons: ['root_multiple' | 'dangling_premise', ...],
  pregateRootCount: number,
  rejected: true,
  rejectionMsg: string,                                 // 起案者向けガイド
  rejectionReasonCode: 'pregate-root-multiple' | 'pregate-dangling-premise',
  triageRejectKind: 'pre-gate-block',                   // ADR-0094 Phase C と同型
}

差戻しメッセージは FAIL_MESSAGES から理由ごとに連結して返す。triage の起案前ゲートと同形式。


9. 分岐 (次ノード)

graph.ts の conditional edge:

.addConditionalEdges('problem_space_pregate', (s) => s?.rejected ? END : 'socratic')
rejected次ノード起案者への表示
true (FAIL)ENDrejectionMsg を返却して終了。pre-gate-block 扱い
false (PASS / INVALID)socratic盲点検出フェーズへ

10. エラー時の挙動

失敗パターン挙動影響
一次 LLM 例外 / 一次 JSON parse 失敗安全側に倒し suspect=true で二次へ送る取りこぼし防止優先
二次 LLM 例外 / 二次 JSON parse 失敗INVALID で通過させるtelemetry で別集計
逐語照合不一致INVALID で通過させる幻覚を評価から隔離
二次の parse は OK だが decide で FAIL差戻し (pre-gate-block)起案者が修正・再投入

設計方針は fail-safe-pass (一次は二次へ・二次は通過)。受付で止めるのは「分析の破れ」が機械的に確定したときだけ。


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

ADR-0142 §5.2.1 盲点 + §5.3 リスクから抜粋:

  • 誤判定由来の差し戻し記録が D-1 に残り続ける: 撤退で graph OFF にしても、precision 70% 未達時の誤判定記録が正典の人手検査基準として残る。OFF 発動時は該当記録に「参照停止」フラグを付与する運用追補が必要。
  • 本 ADR 自身が検問 1 で排除する塊混在と同型: 「分析破れの機械検出」と「行き先規約の制度化」の 2 決定が同居している。独立撤退可能性で許容。将来分離は別 ADR。
  • 代替効果: 審査者が「② で分析チェック済み」と過信し人手レビューが形式確認に退化する恐れ。pass は検問 4 つの通過のみを意味し、分析全正確性は保証しない。Verizon DBIR 2023 同型。
  • 日本語並列節の false positive: 「〜であり、かつ〜」を独立 root と誤解釈しうる。golden eval に 10 件以上の境界例を入れて事前測定する。
  • 逐語引用は実在保証のみ: 引用が判定根拠として論理的に妥当か (faithful but not factual) は担保しない。導入直後 20 run の人手確認で補完。
  • 二次到達時のコスト: 一次で疑いが立った起案だけ二次 (claude-sonnet) を呼ぶ。通常はキャッシュ込みで月数百円規模だが、誤検知率が高いと膨らむ。

12. テストケース

  • パイロット (実装前 K.O.): 受理済み ADR 20 本 + 人工生成陽性例 5 件以上。false positive 30% 超で実装に入らず不採用。
  • golden eval (初期 3 ケース): ADR-0107 修正前 (塊 2 つ)・ADR-0107 修正後 (単一+行き先つき前提)・ADR-0136 (単一) の実検証。
  • 日本語境界例: 「並列節を含む単一決定」起案 10 件以上を golden eval に追加し root 抽出 precision を事前測定。

実行: prompt-cicd フローの一部。詳しくは /Users/ts_kuma/projects/bizlp/doc/prompts/production/gate0a-pregate-{primary,secondary}/ 配下の eval セット。


13. 過去の設計判断ログ

日時変更経緯
2026-06-12ADR-0142 受理 (PR #1835 マージ)② 受付層の分析意味検査の空白を埋める受付ノードとして起案
2026-06-13Phase A パイロット runner で K.O. 通過 (PR #2038)受理済み 20 本 + 人工陽性例で false positive < 30% を確認
2026-06-15Phase B 本番稼働 (PR #2043)graph 配線 + 受付ノード本体投入
2026-06-19月次集計 SQL 整備 (PR #2198)drp/queries/adr-0142-pregate-observation.sql で precision / evidence 一致率を観測

14. 関連リンク