• Status: Accepted (PR #1914 merge = 受理の規約により 2026-06-12 受理・代表取締役判断)
  • Mode: Standard
  • Kruchten Type: Executive
  • Scope: platform
  • Implementation Status: Done (PR #1917 — workflow docs-vectorize.yml + secrets 2 点。ローカル同一コマンドで 801 docs→2,226 vectors 検証済み・merge 後に初回発火 success 確認)
  • 起案者: [email protected]
  • 起案日時 (JST): 2026-06-12 23:43
  • 承認日時 (JST): 2026-06-12 23:56
  • Approver Role: platform
  • Approver Who: [email protected]
  • Driver: [email protected]
  • Consulted: Decision Pipeline AI 審査 (Gate 0-4)

コンテキスト

§1.1 背景

docs サイトの RAG 検索 (ADR-0069 の docs 単源 RAG chatbot・docs-search worker + Cloudflare Vectorize) の知識を更新する scripts/docs-vectorize.mjs は手動実行のみで CI 配線がゼロである (2026-06-12 実査: .github/workflows/ 26 本に vectorize への参照なし)。新規 ADR 受理時の導出物マップ (同日実査) では、ADR ページ・INDEX.md・adr-index.json・docs サイト nav・doc-news・handover 残タスク・相手側 ADR ページへの辺注入まで全て機械化済みで、検索インデックスだけが唯一の手動ギャップとして残っている。

§1.2 現状 (As-Is)

  • ingest は docs/ 全 md → 1000 token チャンク → POST /ingest (Basic Auth・keychain の DECISION_PIPELINE_AUTH と共用) → Vectorize upsert (embedding = @cf/baai/bge-base-en-v1.5・ADR-0069)
  • チャンク id は内容 hash ベースの upsert で再実行は冪等 (全件再 ingest しても重複しない)
  • tasks/prompts/ は恒久除外 (ADR-0134 決定 4・lint ガードあり)
  • 削除済みファイルの残骸ベクトルを掃除する API は worker に存在しない (本決定では扱わない・前提へ)
  • 実行の契機が人間の記憶頼みのため、最後の ingest がいつかを示す記録もない

§1.3 課題

手で docs-vectorize.mjs を実行しない限り、新規 ADR も改訂ページも RAG 検索に載らず、chatbot は古い知識のまま回答する。受理時の自動更新マップで唯一の手動ギャップが構造的に残っている。

§1.4 制約・要件

  • ingest 失敗が docs PR の merge や Pages 公開をブロックしないこと (K.O.)
  • 既存の worker API (/ingest Basic Auth) と docs-vectorize.mjs は無変更
  • tasks/prompts/ 除外規約 (ADR-0134) を維持
  • 削除済みファイルの残骸掃除は本決定の対象外 (worker に delete API がないため)

§1.5 目標 (To-Be)

docs 配下を変更する PR の main merge をトリガーに、人手ゼロで検索インデックスが更新され、実行履歴が Actions に残る状態。Non-Goals: 削除済みベクトルの掃除、差分 ingest 化、検索結果品質メトリクスの計測基盤構築。

決定

docs 配下を変更する PR の main merge をトリガーに、GitHub Actions workflow (docs-vectorize.yml) で node scripts/docs-vectorize.mjs を全件 ingest として自動実行する。Actions secrets 2 点 (DOCS_SEARCH_AUTH_USER / DOCS_SEARCH_AUTH_PASS) を登録し、concurrency で連続 merge を集約、workflow_dispatch で手動回復経路を併設する。スクリプト本体および worker API は無変更。

展開:

  1. workflow 新設 (docs-vectorize.yml): on: push: branches: [main], paths: ['docs/**.md'] + workflow_dispatch。job は node scripts/docs-vectorize.mjs を実行するのみ
  2. secrets 2 点: DOCS_SEARCH_AUTH_USER / DOCS_SEARCH_AUTH_PASS を GitHub Actions secrets に登録。失効時の再同期手順を workflow コメントに明記 (deploy.yml の secret 失効で "entity not found" を踏んだ教訓の横展開)
  3. 全件 ingest のまま運用 (差分化しない): hash ベース upsert で冪等のため最も単純で安全。実測規模 (docs 約 460 md) では実行時間・embedding 従量とも軽微
  4. 非ブロッキング設計: merge 後トリガーのため構造的に独立。失敗時は workflow_dispatch で手動回復
  5. 同時実行の抑制: concurrency で連続 merge 時は最後の 1 回だけが走る

判断基準 (Decision Drivers)

3.1 評価軸

#重要度 (係数)案件特有の解釈
1#usable[Must] (×2.0)merge 後、人手ゼロで検索結果に反映される。実行履歴が Actions に残り「いつ ingest したか」が追える
2#reliable[Must] (×2.0)ingest 失敗が docs の公開 (Pages ビルド) を阻害しない。再実行が冪等で安全
3#efficient[Medium] (×0.5)手動実行の記憶コスト・実行忘れによる検索の古さを解消する

K.O. criterion: Must 軸の score < 3 は不採用。ingest 失敗が docs PR の merge や Pages 公開をブロックする設計は採用しない。

3.2 評価軸 × 案スコア表

係数採択案 (merge トリガー)案 B (手動継続)案 C (日次 cron)案 D (差分 ingest)案 E (Pages ビルド内)
#usable×2.051354
#reliable×2.054431
#efficient×0.541343
加重和 (正規化)0.9800.4600.7600.7800.500
K.O. 通過 (Must ≥3)❌ (#usable=1)❌ (#reliable=1)

検討した代替案 (Alternatives Considered)

  • 案 B: 手動運用の継続 — 唯一の手動ギャップが残り、実行忘れ = 検索の知識の古さが構造的に続く。実行記録も残らない。K.O. (#usable < 3) で不採用
  • 案 C: 日次 cron — 実装は同程度だが、merge から最大 24 時間の反映遅延が常態化する。docs 変更がない日も空回りする。イベント駆動 (merge トリガー) が契機として正確で不採用
  • 案 D: 差分 ingest (変更ファイルのみ) — push イベントの changed files 抽出ロジックが増え、force 系や複数 commit push での取りこぼしリスクを負う。現規模では全件再実行が数分・数円で済むため複雑化に見合わない。将来の最適化として保留
  • 案 E: docs-build.mjs (Pages ビルド) 内で実行 — Pages のビルド環境に worker への書込 secret を渡すことになり、公開ビルドと外部書込の権限が混ざる。ビルド失敗と ingest 失敗が連結し K.O. に抵触するため不採用

影響 (Consequences)

§5.1 正の影響 (Good)

  • 新規 ADR 受理を含む docs 変更が自動で RAG 検索に反映され、受理時の自動更新マップの手動ギャップが消える
  • ingest の実行履歴が Actions に残り「最後にいつ更新されたか」が追える
  • スクリプト・worker 無変更で完全可逆 (workflow 削除のみで撤退可能)

§5.2 負の影響 (Bad)

  • Actions secrets 2 点が増え、失効時は workflow が落ち続ける (検知は workflow 失敗通知に依存)
  • 削除済みファイルのゴーストベクトルが Vectorize に蓄積し続ける構造問題が残る (worker に delete API なし)。ingest 頻度が上がるほど累積速度も上がる
  • 間接生成ワークフロー (例: ADR-0146 の派生ビュー注入) が docs/*.md を別コミットで更新した場合、paths: ['docs/**.md'] フィルタをすり抜け ingest がスキップされる可能性がある

§5.3 中立・トレードオフ (Neutral / Trade-offs)

  • concurrency 方針: cancel-in-progress: true (最後の 1 回に集約) を採用。途中キャンセル時は新旧チャンクの一時的非一貫が発生しうるが、hash ベース upsert で冪等のため最終ジョブ完走で整合性が担保される。連続 merge 時の worker 負荷と重複書込を回避する優先度を上位に置いた
  • docs 規模増加リスク: 現規模 (460 md) での手動全件実行実績を根拠としており、worker 側 CPU 時間制限 (30 秒) に /ingest が引っかかるシナリオは現規模では未観測。docs が 600 md を超えた時点で実行時間と worker 側 CPU 使用率を計測し、差分化検討の起票判断とする (撤退条件参照)
  • ゴーストベクトル先送りの期限化: 削除済みページが検索上位に出現する事例が 3 件、または本決定採用から 6 ヶ月以内に、docs-search worker への delete API 追加 ADR を起票する (観測待ちではなく期限付き)
  • 間接生成ルートの取りこぼし対策: docs/*.md を生成・コミットするワークフローが新規追加される際は、そのワークフロー完了後に workflow_dispatch で docs-vectorize を呼び出す手順を必須化する。現状の自動更新マップ上の間接生成ルートは実装時点で洗い出し workflow コメントに記録する

撤退条件 (Rollback Plan)

  • ingest 起因で docs-search worker の検索品質・可用性に支障が出た事例が 2 件以上 (例: 手動検索で期待ヒットゼロが 2 件、または ingest 直後の検索失敗報告 2 件) → workflow を無効化し手動運用へ戻す
  • workflow 失敗が 1 週間以内に 3 回以上 → secrets 再同期 → 回復しなければ worker 側調査へ切替
  • Workers AI / Vectorize の従量が想定の 10 倍 (月数千円) を超えた場合 → 頻度を日次 cron (案 C) へ縮退。docs が 920 md (現状の 2 倍) に達した時点で全件 ingest のコストと実行時間を再計測し差分化移行可否を起票
  • docs が 600 md を超えた時点で全件 ingest の実行時間と worker 側 CPU 使用率を計測 (worker 30 秒制限の早期検知)
  • 撤退操作: workflow ファイルの削除または on: の無効化 PR のみ (スクリプト・worker は無変更のため完全可逆)

コスト試算

  • 実装 約 0.2 人日: workflow 1 本 (push + workflow_dispatch + concurrency) + secrets 登録 + 動作確認 (merge 1 回で Actions 成功と検索ヒットを確認)
  • 運用従量: 全件 ingest 1 回 = docs 約 460 md・数千チャンク規模の embedding (@cf/baai/bge-base-en-v1.5・Workers AI 従量) で数円以下/回。docs を触る merge 頻度 (直近実績 数回〜10 回/日) でも月数百円未満
  • 効果: 手動実行の運用 (記憶・手順・実行忘れの調査) が消える

Confirmation

  • 検証手段: ① workflow 成功率を Actions 履歴で確認 (失敗時は GitHub の workflow 失敗通知)。通知は Slack / Teams チャネルに接続して見落としを防ぐ (実装時に接続手順を workflow コメントに明記) ② 受理直後の新規 ADR タイトルで docs 検索を叩き、ヒットすることを月次でスポット確認 ③ secrets ローテーション期限 (組織ポリシー準拠・90 日) をカレンダーリマインダーで管理し、失効前に再同期 ④ workflow 失敗が 1 週間以内に 3 回以上で secrets 再同期判定 (撤退条件と連動)
  • 実行頻度: ① merge 毎 (自動)、② 月次、③ 90 日毎、④ 常時 (Actions 履歴ベース)
  • 違反時対応: 失敗が連続したら secrets 再同期 → 手動 workflow_dispatch で回復。回復しない場合は worker 側 (/ingest) の調査へ切替

Review After

  • 次回レビュー: 2026-12-12(運用 6 ヶ月後。全件 ingest 方式の実行時間・従量が docs の成長に見合っているか〔差分化 = 案 D への切替判断〕と、残骸ベクトル〔削除済みページ〕の実害有無を再評価する時期)
  • レビュー主体: docs 運用の所有者(現任 = 代表取締役)
  • 前倒しトリガ: ① 撤退条件のいずれかに抵触した時 ② docs の md 数が現規模の 3 倍 (約 1,400 本) を超えた時 — 全件 ingest の実行時間・従量が線形に増えるため ③ docs-search worker の /ingest API・チャンク化仕様の変更時 (ADR-0069 改訂) — workflow の前提契約が変わるため ④ ADR-0146 の派生ビュー注入が docs/*.md を別コミットで更新する経路が実装された時 — §結果で挙げた paths: ['docs/**.md'] フィルタすり抜け (間接生成コミットで ingest がスキップされる) が現実化するため。0146 実装時に派生ビュー更新コミットが本 workflow の発火条件を満たすか確認し、すり抜けるなら workflow_dispatch 連携 or trigger 調整で塞ぐ (DOC-OPS-29 候補2 ③)

参照 (References)

  • 関連 ADR:
    • ADR-0069: docs 単源 RAG chatbot (Worker + Vectorize + ingest スクリプト) — follows_up_on (本決定は 0069 が導入した ingest の実行契機を手動から CI へ移す運用フォローアップ。チャンク化・embedding・worker API は無変更)
    • ADR-0134: tasks/prompts の恒久除外 — relates_to (ingest 対象の除外規約は本決定後も lint ガードごと維持される)
    • ADR-0146: 早わかりの派生ビュー化 — relates_to (0146 実装で docs ページに生成ビューが注入されると、その本文も次回 ingest で検索対象になる。受理時自動更新マップを完成させる同じ方向の決定)
  • 関連 PR/Issue: -
  • 外部資料: -