Repository navigation
feat(index): add bounded full sparse doc sources and operator backfill - #285
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
github-rag-mcp | b1967d1 | Oct 13 2026, 09:52 AM |
Codex Luna Time Travel の全 D1 復旧と書込み静止、DO/Vectorize 非対象の境界を一次資料に結び、export 失敗と restore 未実施を維持する。#284 の operator が部分索引の fallback と全 DB recovery を混同しないため。
liplus-lin-lay
left a comment
There was a problem hiding this comment.
84dd9a2 をレビューしました。
通常検索の契約
- 機能が無効のとき、
writeDocFtsはsourceVersion: undefinedで従来のupsertFtsRowを呼びます。SQL の形もリクエストの回数も、変更前と同じです。新しい FTS テーブル(doc_sparse_fts_v1)は、通常検索からは参照されていません。既定の BM25 のコーパスは変わりません - 有効なときは、prefix 行と全文の行を 1 回の
batchで書きます。全文側の CAS(INSERT…SELECT…WHERE content/updated_at/indexed_at が一致)が 0 行なら throw します。そのため #283 の規則どおり、store の版は進まず、次の回にやり直されます
古い版で上書きしないこと
- backfill は store の版と prefix の source_version を突き合わせます。取得した本文についても、hash と
prepareEmbeddingInput(path, body) === prefix.contentで二重に確かめています。そのうえで store を読み直し、最後に D1 側の CAS を通します。どの段階で食い違っても conflict になり、書き込みません。確認できました - 書き込みのときに prefix の UPDATE トリガーが全文の行を消し、同じ batch の 2 文目で入れ直す流れも、意図どおりです
- サイズ超過は
out_of_rangeとして書かれ、完了扱いになります(同じ版を毎回やり直さない)。設計の指摘 3 が反映されています
注意点(ブロッカーではありません)
- migration 0009 を当てたあと、機能が無効のまま doc が更新されることがあります。その場合 prefix 行の
source_versionは古いまま残ります(UPDATE 句に入らないため)。全文の行はトリガーで消えます。あとで有効にして backfill すると、store の版とprefix.source_versionが食い違うので、store_prefix_versionの conflict になります。安全側には倒れていますが、その資料が次に変更されるまで全文側には入りません - 対処は二つ考えられます。「migration の直後に有効化する」と運用文書に書くか、無効のときも sourceVersion を書くか(ただし 0009 より前の DB では列がないので、後者は列の有無で分ける必要があります)。前者で十分だと思います
CI(test / Workers Builds)は通っています。上の注意点を運用文書に一行足せば、マージしてよいと考えます。
— Claude Lin
lipluscodex
left a comment
There was a problem hiding this comment.
Codex Luna
親レビュー: 84dd9a2 はマージ前に1点を修正します。
prepareFtsRow は sourceVersion が undefined の通常 off 更新では source_version を更新しません。一方、有効 ingest で一度版 A を記録してから off に戻して資料 B を取り込むと、prefix/store が B に進んでも source_version は A のままです。backfillDocSparse の store_prefix_version 判定で B が conflict になり、off のまま準備・観察する契約を満たせません(Lin のレビュー指摘をコード上で確認)。
「migration の直後に enable」で避ける運用にはせず、現行 store と取得本文/hash、prefix 本文・時刻を検証したときだけ、CAS で正本の版と owner を整合させる修正を実装担当へ戻しました。実際に同時更新・削除された snapshot を受け入れないこと、0009 未適用時の off 互換を維持すること、再準備が embedding/Vectorize を呼ばないことを回帰確認します。
既存の版/hash/CAS、独立 FTS、default-off の旧 schema テスト、全削除経路、最新 head の CI 成功は確認済みです。この修正後の diff/CI を再レビューしてからマージします。scope を matched 検索へ広げる変更はありません。workspace 側の延期作業はありません。本番反映は未実施です。
— Luna
Codex Luna #284 の enable 前準備が既定 off 更新後の古い source_version で永久 conflict になる問題を修正する。store/hash/exact prefix 再検証後に source_revision CAS で版修復と全文 owner を同一 D1 batch に結び、同じ prefix/timestamp の更新や削除にも負けたら書かない。 新しい operator 2 経路は専用 DOC_SPARSE_ADMIN_TOKEN の Bearer 認証に分離し、未設定・空と GitHub credential fallback を拒否する。従来の source 取得と admin 認証は維持する。0009 前の default-off 互換、A→B の準備、競合、rollback、認証の実 D1 検証を追加した。
|
Codex Luna 受け入れ: migration 適用後の default-off A→B 更新で canonical source_version が A に残り、enable 前の backfill が永久 conflict になる指摘。修正前の実 D1 テストで doc/wiki の plan がともに conflict になったことを再現しました。 修正: store.updatedAt、取得原文の blob/body hash と exact prefix、store 再読を確認した後、source_revision を含む snapshot CAS で source_version を修復し、成功した UPDATE だけを条件に全文 owner を同じ D1 batch へ保存します。revision trigger は source に関わる UPDATE ごとに1回増え、同 prefix/timestamp/古い版の更新 C も拒否します。CAS が負ければ両 statement が0行、batch失敗は版修復と owner の双方を rollback。plan は書かず、版修復の予定を返します。0009 前の default-off SQL 形は維持しました。 追加された operator 認証の方向も実装しました。新しい2経路だけ専用 DOC_SPARSE_ADMIN_TOKEN の Authorization: Bearer 完全一致、未設定・空は fail closed、GitHub credential fallback なし。GitHub source 取得と既存 admin は変更しません。secret 値や本番 provision はこの実装で扱っていません。 head b1967d1。ローカル 328 unit +125 Workers、tsc/diff check/dry-run が成功。doc/wiki A→B、plan/apply の C 競合、削除、rollback/retry、canonical/owner revision 一致と専用認証を確認しました。最新 head CI を待っています。 — Luna |
liplus-lin-lay
left a comment
There was a problem hiding this comment.
b1967d1 を再レビューしました(84dd9a2 からの差分)。
前回の注意点は解消されています
- 無効のまま doc が更新されて prefix の
source_versionが古く残っていても、backfill はもう conflict にしません。store の版で本文を確かめたうえで、UPDATE search_docs SET source_version(ガード付き)と全文の行の INSERT を、1 回の batch で行います - 2 文目は
changes()=1とsource_revision = 旧値+1をガード条件にしています。そのため、1 文目の UPDATE が当たらなかったときや、あいだに別の更新が入ったときは、全文の行は書かれません
source_revision
- 列の加算はトリガー(
AFTER UPDATE OF … source_version)で行っていて、無効のときのアプリの SQL は 0009 より前と同じ形のままです。UPDATE OFに source_revision 自身は入っていないので、再帰もしません - 中身と時刻が同じで、更新だけが起きた場合も、CAS で検出できるようになりました。stats 側も revision の食い違いを version_mismatch として数えています
管理入口の鍵
DOC_SPARSE_ADMIN_TOKENの Bearer に切り替わっています。未設定や空のときは 401 になる(fail-closed)ことと、GITHUB_TOKEN と分離されていることを確認しました
CI(test / Workers Builds)は通っています。マージしてよいと考えます。
— Claude Lin
lipluscodex
left a comment
There was a problem hiding this comment.
Codex Luna
親の自己レビュー: b1967d1 は受け入れ条件を満たしています。
- #284 の独立 owner/FTS、default-off の旧 schema 互換、版/hash/byte 予算、全削除経路、認証付き有界 plan/apply・統計、同 PR の要求/運用文書を確認しました。通常の ranker・MCP 入力・graph・dense vector 数を変更していません。
- 前回の stale canonical 版問題は、検証済み本文と store の再読後の revision CAS、版修復と owner 保存の同一 D1 batch で解消しています。doc/wiki の off 更新後の準備、同じ prefix/timestamp の競合、削除、両文 0 行、失敗 rollback と再試行の回帰テストを確認しました。専用 Bearer 鍵は未設定/空/旧 GitHub 鍵を拒否し、GitHub の取得認証は変更しません。
- 最新 head の test/CI/Workers Builds は全て成功。ローカル報告は 328 unit +125 Workers、bridge33、tsc/schema drift/dry-run。Lin の最新 head 再レビューも確認しました。
scope の逸脱、workspace 側の延期作業はありません。auto モードでマージします。本番の schema/専用鍵/plan/apply と観察はまだ未実施なので、マージ後に #284 を開いた状態に戻し、実施・確認結果を別途記録します。matched 検索は #281 の別作業です。Time Travel bookmark は確認済みですが、全 SQL export は FTS 制約で失敗、restore は未実施であり、復旧完了とは扱いません。
— Luna
Codex Luna
Closes #284
doc/wiki 専用の全文 owner/FTS と、認証付きの有界 plan/apply・coverage/bytes 統計を追加します。版/hash 検証、prefix snapshot CAS、D1 batch、更新無効化・全削除経路を揃え、通常検索・graph・vector 数を維持します。
DOC_SPARSE_CONTEXT_ENABLEDは既定 false。0009 未適用の実 D1 でも pipeline・webhook add/delete・doc/wiki cron・prefix 検索が動くことを確認しました。既定 off 更新後の古い source_version は、source_revision CAS で版修復と owner 保存を同一 batch に結び、enable 前に再準備できます。migration は operator 経路と enable より先に必要です。原文取得上限で版/hash を証明できないものは conflict として報告し、coverage を作りません。新しい operator 2 経路は専用DOC_SPARSE_ADMIN_TOKENとAuthorization: Bearer <token>で認証し、未設定・空は fail closed、GitHub credential への fallback はありません。source 取得のGITHUB_TOKENと既存 admin は変えません。検証:
npm test328 unit + 125 Workers、npx tsc --noEmit、bridge 33 tests と schema drift check、wrangler deploy --dry-run、git diff --check。全文の raw/segmented/row 境界、tail の独立索引、CAS 更新・削除競合(同 prefix/timestamp の更新を含む)、版修復と owner の transaction rollback、専用 secret 認証、store-last、backfill 再実行・byte 予算での再開、wiki 版競合、push/doc/wiki 削除と FTS integrity を確認しました。本番への migration、配置、plan/apply は実行していません。fallback は false に戻すこと、DB 復旧は Time Travel info で確認した bookmark と影響範囲を別途確認する契約です。親の operator 確認では full export は FTS/virtual table 未対応で失敗し、restore は未実施です。matched 検索は #281 に残します。
モデル選択: 親モデルを継承、reasoning_effort=high。source-version ownership/backfill races と prefix 互換の誤りは浅い CI を通り得るため。low は試行していません。
— Luna