最終更新: 2026/06/22 18:56
DRP 内部実装マップ
役割: Worker 内部の実装ファイル構成・ノード配置・エラーハンドリング箇所を一覧する(IDD-001)。外部接続の詳細は EDD-005 外部 I/F 一覧。アーキテクチャ図(Container / Sequence)は アーキテクチャ図。Pipeline session の状態遷移は 状態遷移仕様。
1. ASCII 詳細図(実装ファイル参照付き)
[起案者 (社内メンバー / 業務委託パートナー / 代表取締役)]
↓ ブラウザでアクセス(Cloudflare Access + Basic 認証)
[Hono Web UI on Cloudflare Workers(フロントエンド)]
│ src/index.ts / public/index.html
↓ POST /draft(起案者・タイトル・コンテキスト・候補)
[LangGraph TS StateGraph on Cloudflare Workers(審査員)]
│ src/graph.ts / src/state.ts
├─ Gate 0 (triage node) : ADR 要否 / モード判定(Light / Standard / Critical)
│ src/nodes/triage.ts
├─ Gate 0a (problem_space_pregate) : 問題空間切り分けプリゲート (ADR-0142 / 差戻し型・本番稼働 2026-06-15)
│ src/nodes/problem_space_pregate.ts
│ 一次: gemini-flash で属性分岐シグナル抽出 → 疑いありのみ 二次: claude-sonnet で主張グラフ (問い/案/論拠) へ構造化分解
│ 判定は決定論コード src/nodes/problem_space_decide.ts (root の問い ≥2 ⇒ 塊複数 / 行き先なし前提 ⇒ fail)
│ 塊の混在・対症療法・宙に浮いた対応策・行き先なし前提を検出 → END で差戻し (判定理由 + 逐語引用を telemetry 記録) / INVALID (評価不能) は socratic へ
│ temperature 0・厳格 JSON schema・プロンプトハッシュキャッシュ・graph 分岐で OFF 可能
├─ Gate 1 (blind-spot detection) : 盲点検出エンジン (ADR-0071 / 差戻しなし・情報提供型)
│ src/nodes/socratic.ts
│ DA (T=0.95) + PM (T=0.8) 並列 → Judge (T=0.2) → blindSpotFindings
│ (PR body の Blind-spot Report に全 findings を severity 付き表示)
│ Constitution 22 観点から 3 観点を**原稿内容シードで決定的選択** (FNV-1a+mulberry32 / Part3)
│ → 同一原稿は同一視点・同一盲点で Cross-Validation 収束を担保 (`SOCRATIC_DETERMINISTIC` 既定 ON)
├─ Body generation node : `docs/adr/_template.md` を system prompt に注入して ADR 本文生成
│ src/nodes/body_generation.ts
├─ Gate 4 (scoring node) : 50 点満点スコアリング(Mode 別閾値 Light 35 / Standard 40 / Critical 45 未満は END で差戻し)
│ src/nodes/scoring.ts
│ N=5 Self-Consistency: 同一プロンプトで 5 回並列採点 → 多数決 (ADR-0056)
├─ Cross-Validation node : 盲点 × Must 軸の整合検証(critical 盲点×Must×undermines で END 差戻し / ADR-0076・0092)
│ src/nodes/cross_validation.ts (SSoT: prompts/production/cross-validation/ / Part1 で監査 gap ADR-0085 解消)
│ (盲点 finding が Must 軸スコアの前提を毀損するか claude-opus で判定 / エラー時 fail-open)
│ **ライフサイクル整合バー (Part1)**: 実装時にしか検証できない前提 (決定性・実コスト減・CI 挙動等) は、
│ 本文に**この risk を実際に防止/検出する具体的緩和機構** (具体設計 / Confirmation / 撤退条件) があれば undermines=false。
│ 単なる Consequences の言及・コスト計上・関連記述は addressed と認めない (= 起案段階での過剰要求を回避しつつ FN を作らない)
├─ Cross-Val loop-breaker : bounded rounds で停止性を確保 (Part4 / ADR-0109 — 文献処方「LLM ループ外の検証器が必須」)
│ (consumer 内・純ロジック) src/nodes/crossval_loopbreaker.ts / src/queues/pipeline_consumer.ts / src/audit/persistence.ts:getPriorCrossValVerdicts
│ judge: trailing 連続却下チェーン (非隣接却下は除外) で (a) 盲点が「移動」=goalpost、または
│ (b) 連続却下が round-cap (`CROSSVAL_ROUND_CAP` 既定3) 到達 → escalate。同一盲点の持続却下は cap より優先で reject 温存 (FN=0)
│ escalate 時: rejected=false に降ろし slug+numbering+webhook 実行 → **PR 起票**、本文に
│ buildResidualRiskSection() で「Known Limitations / Escalated Residual Risks」節 (HITL マーカー ``) を付与。
│ 人間の merge=受理 / close=却下 が終端。`CROSSVAL_LOOPBREAKER` 既定 ON・"false" でロールバック (常に自動 reject)
├─ Gate 2 (consistency node) : 過去 ADR 全件取得 → claude-opus で Conflict / Supersede 判定
│ src/nodes/consistency.ts
│ (CONFLICT 検出 + 起案ドラフトに supersede 宣言なしの場合は END で差戻し)
├─ Gate 3 (parallel_review node) : 3 モデル並列レビュー (Promise.all、差戻しなし・情報提供型)
│ src/nodes/parallel_review.ts
│ ├─ Gemini Pro (deep think) : ビジネスインパクト / アーキ整合性 / 長期負債リスク
│ ├─ Claude Opus : 論理的一貫性 / 問題定義と決定のつながり / 撤退条件の現実性
│ └─ GPT o3 (reasoning_effort) : 技術的実現可能性 / コスト試算 / 完了条件の検証可能性
│ (各モデルのエラーは個別 catch で吸収 → パイプライン継続)
├─ Policy Alignment node : 会社固有方針との整合評価(差戻しなし・情報提供型 / claude-opus)
│ src/nodes/policy_alignment.ts
├─ Slug node : タイトル → snake_case slug
│ src/nodes/slug.ts
├─ Numbering / Webhook node : 採番リクエスト + GitHub Actions 起動 + 3 モデルレビューを PR 本文に転記
│ src/nodes/numbering.ts / src/nodes/webhook.ts
│
│ (全 Gate 実装完了 — 全 LLM 呼出は LiteLLM Gateway 経由)
↓
[LiteLLM Gateway on GCP Cloud Run]
│ drp/litellm/
├─ 機密情報マスキング callback(取引先名・金額・scriptId・OAuth 除去、fail-fast)
│ litellm/masking.py
├─ Multi-Provider 切替: vertex_ai/gemini-flash・gemini-pro / anthropic/claude-sonnet・claude-opus / openai/gpt-o3
│ litellm/config.prod.yaml
└─ API キーは GCP Secret Manager で集中管理
↓ 合格時のみ Webhook
[Cloudflare Queues + Durable Objects(非同期実行 / ADR-0066)]
│ src/queues/pipeline_consumer.ts / src/do/pipeline_session.ts
├─ ?async=true 時: triage+socratic 同期 → Queues enqueue → Consumer Worker が残り Gate 実行
├─ PipelineSessionDO に状態保存 → GET /chat/status/:sessionId で polling
└─ DLQ (pipeline-queue-dlq) + max_retries=3
↓
[GitHub Actions(バックエンド・書記)]
│ .github/workflows/drp.yml
├─ 採番(concurrency: adr-numbering で排他制御)
├─ claude/decision-* ブランチ作成
├─ docs/adr/NNNN-slug.md 書込
└─ Status: Proposed の PR 作成
↓
[代表取締役]
├─ adr-kit(`/adr-kit:lint`)で 4 ゲート lint(Completeness, Evidence, Clarity, Consistency)
└─ Branch Protection Rule により Accepted / Superseded は代表取締役のみ実行可能
2. 構成要素マッピング
外部接続(LLM Gateway / GitHub / LangSmith)の接続先・認証・障害時挙動の詳しい説明は EDD-005 外部 I/F 一覧 にある。本表は内部構成要素を含む俯瞰用。
| 機能 | 担当 | コード / 設定 |
|---|---|---|
| 起案入口(Web UI) | Hono on Cloudflare Workers | src/index.ts / public/chat.html / wrangler.toml |
| StateGraph / Triage / Problem-space Pregate (ADR-0142) / Blind-spot Detection (ADR-0071) / Scoring / Consistency / Parallel Review / 本文生成 / Slug | LangGraph node | src/graph.ts / src/nodes/*.ts(プリゲートは problem_space_pregate.ts + 決定論判定 problem_space_decide.ts) |
| triage 派生フィールド整形の集約 (ADR-0103 案 C′) | shared triage module (handler / consumer 共通呼出) | src/triage/shared_triage.ts |
| 非同期実行 (ADR-0066) | Cloudflare Queues + Durable Objects | src/queues/pipeline_consumer.ts / src/do/pipeline_session.ts |
| エラーハンドリング (null guard) | graph.ts / index.ts / pipeline_consumer.ts / chat.html | conditional edge s?. 防御 + preGraph null → 502 + lastResult null → error + pollSession null guard |
| LLM パラメータ管理 (ADR-0056) | prompt.meta.yaml + KV | prompts/production/<id>/prompt.meta.yaml / scripts/prompt-kv-push.mjs |
| LLM 呼出 (3 プロバイダ統合) | LiteLLM Gateway on Cloud Run | → 詳しくは EDD-005 |
| 採番 + PR 作成 | GitHub Actions | .github/workflows/drp.yml |
| lint (4 ゲート / file:line citations) | adr-kit | .claude/skills/adr-kit/ (Skill として対話実行) |
| ADR 形式の補助 lint (CI gate) | scripts/adr-lint.mjs | 5 ルール (numbered-header / context-section / decision-section / no-placeholder / min-length) |
3. エラーハンドリング箇所(null guard 一覧)
整備: 2026-05-27 PR #1035 / #1036 / #1037。
| 防御箇所 | ファイル | 挙動 |
|---|---|---|
| conditional edge null state | src/graph.ts | 全 conditional edge で s?.needsAdr / s?.socraticPass / s?.rejected に optional chaining。state が null なら END に遷移 |
| preGraph null return | src/index.ts | preGraph.invoke() が null を返した場合 502 レスポンス |
| preGraph null return (consumer) | src/queues/pipeline_consumer.ts | null なら throw → DO に status: 'error' を記録 |
| lastResult null | src/queues/pipeline_consumer.ts | streamEvents 完了後に lastResult が null なら throw。on_chain_end で event.data?.output が truthy なら常に更新 |
| pollSession null result | public/chat.html | status: 'complete' だが result が null の場合エラーメッセージ表示 (crash 防止) |
変更履歴
| 日時 | 変更 |
|---|---|
| 2026-06-16 | ② 受付プリゲート(Gate 0a / problem_space_pregate.ts + 決定論判定 problem_space_decide.ts・ADR-0142)を ASCII 図と構成要素マッピングに追加。本番稼働 2026-06-15 を反映 |
| 2026-06-07 | 初版 — README §8.2・§12 エラーハンドリング表から移植(経緯: ADR-0117) |