このファイルは main workspace の Claude Code セッションで実行する実装プロンプト


あなたの役割

drp/src/nodes/webhook.tsPR title 生成ロジックにある [ADR] 二重付与バグを修正 し、wrangler deploy するまでが完了 DoD


問題の詳細

現象

Decision Pipeline 経由で自動生成される PR のタイトルが [ADR] [ADR] ... と prefix が二重付与される。

実例 (本セッション中に発生した 3 件):

PRタイトル
#837 (ADR-0052)[ADR] [ADR] Decision Pipeline UI: retroactive validation モード...
#834 (ADR-0051)[ADR] [ADR] docs/_config.json nav 未登録の .md ファイル検出 lint を追加
#843 (ADR-0053)[ADR] [ADR] ADR 本文 §3 に判断基準節...

原因

  • operatorKV draft の title フィールドを [ADR] ... 形式で書く (PR title として完成形を意図)
  • Webhook ノード (webhook.ts:170) も [ADR] を prepend する

両者の善意が重複して [ADR] [ADR] ... になる。

該当コード

drp/src/nodes/webhook.ts (line 168-184):

const pr = await githubFetch<{ html_url: string }>(env, '/pulls', {
  method: 'POST',
  body: JSON.stringify({
    title: `[ADR] ${state.title}`,   // ← line 170: ここで重複付与
    head: branch,
    base: 'main',
    body: [
      ...
    ].join('\n'),
  }),
});

実装手順

Step 1: ブランチ作成

git checkout main && git pull origin main
git checkout -b fix/pipeline-webhook-double-adr-prefix

Step 2: webhook.ts の修正

drp/src/nodes/webhook.ts の line 170 付近を以下のように修正:

// Before
title: `[ADR] ${state.title}`,

// After
// state.title が既に [ADR] で始まる場合は重複防止のため除去してから付与
title: `[ADR] ${state.title.replace(/^\[ADR\]\s*/, '')}`,

Step 3: ローカル検証 (任意)

cd drp
# unit テストがあれば実行
# pnpm test 2>/dev/null || echo "no unit tests configured"

# 手動で正規表現の挙動確認
node -e "
  const cases = [
    '[ADR] Decision Pipeline UI',         // 既に prefix あり
    'Decision Pipeline UI',               // prefix なし
    '[ADR]  Decision Pipeline UI',        // 余分な space
    '[ADR-0052] Decision Pipeline UI',    // 番号付き (これは置換されない、別ケース)
  ];
  for (const t of cases) {
    console.log(\`'\${t}' → '[ADR] \${t.replace(/^\\[ADR\\]\\s*/, '')}'\`);
  }
"
# 期待出力:
# '[ADR] Decision Pipeline UI' → '[ADR] Decision Pipeline UI'
# 'Decision Pipeline UI' → '[ADR] Decision Pipeline UI'
# '[ADR]  Decision Pipeline UI' → '[ADR] Decision Pipeline UI'
# '[ADR-0052] Decision Pipeline UI' → '[ADR] [ADR-0052] Decision Pipeline UI'

Step 4: wrangler deploy

cd drp
wrangler deploy

デプロイ確認:

wrangler deployments list | head -3

Step 5: E2E 検証

本番環境で fix の有効性を確認するため、テスト draft を投入 → Pipeline 実行 → PR title を確認:

AUTH_USER=$(security find-generic-password -a "$USER" -s "bizlp-gas-DECISION_PIPELINE_AUTH_USER" -w)
AUTH_PASS=$(security find-generic-password -a "$USER" -s "bizlp-gas-DECISION_PIPELINE_AUTH_PASSWORD" -w)
TEST_ID="test-webhook-fix-$(date +%s)"

# title に [ADR] prefix を含む test draft を投入
curl -X POST -u "${AUTH_USER}:${AUTH_PASS}" \
  -H "Content-Type: application/json" \
  -d "{
    \"id\": \"${TEST_ID}\",
    \"author\": \"test\",
    \"title\": \"[ADR] webhook fix verification (delete me) (Light)\",
    \"context\": \"これは webhook fix の E2E 検証用 test draft。Pipeline を通過させて PR title が単一の [ADR] prefix になることを確認したら削除する。\",
    \"options\": \"\"
  }" \
  "https://decision-pipeline.t-saitoh.workers.dev/drafts"

# その後 chat UI (https://decision-pipeline.t-saitoh.workers.dev/chat) でこの draft を呼び出し、
# Gate 0-4 を通過させ、retroactive=false で create-pr を実行
# → 自動生成 PR のタイトルが「[ADR] webhook fix verification (delete me) (Light)」(単一 prefix) であることを確認

# ※ Light Mode で書いてあるため、Gate 0 で is_adr_worthy=false 判定されて Pipeline 終了する可能性大
#   その場合は title を「webhook fix verification (Light)」(prefix なし) に変えて再投入し、
#   Webhook が単一の [ADR] prefix を付けることを確認するパスもアリ

# 検証完了後のクリーンアップ
curl -X DELETE -u "${AUTH_USER}:${AUTH_PASS}" \
  "https://decision-pipeline.t-saitoh.workers.dev/drafts/${TEST_ID}"
# 検証 PR が作成された場合は gh pr close で取り消し

代替案: 既存の合格済 KV draft (adr-meta-q42-decision-drivers-in-adr-body など、Pipeline 通過済で title に [ADR] を含むもの) の title を一時的に [ADR] なしに書き換え → 再 Pipeline → PR title が [ADR] ... 単一で生成されることを確認。ただし副作用が大きいため不推奨。

Step 6: PR 作成

git add -A
git commit -m "$(cat <<'EOF'
fix(pipeline): PR title の [ADR] 二重 prefix を修正

KV draft の title フィールドに既に [ADR] が含まれる場合、Webhook ノードが
更に [ADR] を prepend して二重付与となっていた (#834 #837 #843 で発生)。

state.title から先頭の [ADR] を正規表現で除去してから付与するよう変更。
title に [ADR] が含まれない場合は従来通り [ADR] を付与 (後方互換)。

Refs: #843 (本 fix の検出元), webhook.ts:170

Co-Authored-By: Claude Opus 4.7 <[email protected]>
EOF
)"
git push -u origin fix/pipeline-webhook-double-adr-prefix
gh pr create --title "fix(pipeline): PR title の [ADR] 二重 prefix 修正" --body "$(cat <<'EOF'
## Summary

Decision Pipeline 経由の自動生成 PR タイトルが `[ADR] [ADR] ...` と二重 prefix になる現象を修正。

## 原因

- operator が KV draft の `title` を `[ADR] ...` 形式で書く
- Webhook ノード (`webhook.ts:170`) も `[ADR] ` を prepend
- → 両者の善意が重複

## 修正

```diff
-      title: `[ADR] ${state.title}`,
+      title: `[ADR] ${state.title.replace(/^\[ADR\]\s*/, '')}`,

state.title が既に [ADR] で始まる場合は除去してから付与。先頭に prefix がない場合は従来動作 (後方互換)。

影響を受けた過去 PR (記録のみ、修正対象外)

  • #834 (ADR-0051)
  • #837 (ADR-0052)
  • #843 (ADR-0053)

Test plan

  • 正規表現の手動 unit テスト (4 ケース): prefix あり / なし / 余分 space / 番号付き別ケース
  • wrangler deploy 成功
  • E2E: test draft を投入 → Pipeline 実行 → PR title が単一 [ADR] prefix を確認 → クリーンアップ

🤖 Generated with Claude Code EOF )"


---

## 範囲外 (本 fix では対応しない)

- **過去 PR (#834, #837, #843) のタイトル修正**: 既にマージ済の歴史記録、無修正で許容
- **operator-prompt 規約の変更**: 「title フィールドに `[ADR]` prefix を入れない」と統一する選択肢もあるが、本 fix で Webhook 側が defense-in-depth で対応するため operator 側の制約を増やさない
- **`[ADR-NNNN]` 形式** (番号付き) の対応: 上記正規表現は `^\[ADR\]\s*` (空白までを除去) なので `[ADR-0052]` のような形式は除去対象外。これは「ADR-NNNN を明示したい意図」と解釈し、別途処理不要

---

## 制約・注意

- **後方互換性**: 既存 KV draft (title に `[ADR]` なし) は従来通り `[ADR] X` の単一 prefix で PR 化される
- **正規表現の限界**: `/^\[ADR\]\s*/` は先頭 `[ADR]` + 任意空白を除去。`[ADR-NNNN]` 形式は除去されないため、もし operator が `[ADR-0053] xyz` を渡したら `[ADR] [ADR-0053] xyz` になる (許容、ADR 番号明示の意図と解釈)
- **deploy 後の確認**: 既存 KV drafts (5 件) の title に `[ADR]` 含むものを次回 Pipeline 通過時に確認可能、緊急ロールバックは `wrangler rollback`
- **コミットメッセージ規約**: `fix(pipeline):` prefix で conventional commits 準拠
- **報告**: 実装 PR 作成後、代表取締役氏に PR 番号 + E2E 検証結果を chat で報告