1d6dde4a01
leo 2026-08-11 拍板(D68,system-dev/wiki/decisions-summary.md):補算向量要照時間 由新到舊、且每天有額度上限,不能一次把 Workers AI 每日免費 10,000 neurons 燒光 (與萃取共用同一份額度,見 ops-facts.md)。對應 Leo/Arcrun#85 列出的三個缺口: ① 補算是由舊到新(ORDER BY created_at ASC)② 沒有每日額度上限 ③ 沒有任何自動觸發。 改動: - backfillEmbeddings:ORDER BY created_at DESC(新到舊),並在打 AI 前依 env.EMBED_BACKFILL_DAILY_LIMIT(未設用推導出的預設值 1800,算式見 embed.ts 註解) 截斷候選、額度用完即停手不再打 AI。額度用量存在 entries 表單一列 (entry_type='embed_backfill_usage',UTC 日期切),不新增表(D38)。 - embedOnWrite / backfillEmbeddings 成功嵌入後在既有 content_hash 欄位蓋上 現行模型名(世代戳記),修復 leo21c 資料還原案:從備份整批灌回的列帶著對已退役 768 維索引的 is_embedded=1,現行 1024 維索引永遠不會補到它們。 - 新增 reconcileEmbedGeneration + POST /embed/reconcile:對 is_embedded=1 但 content_hash 非現行世代的候選,問 Vectorize.getByIds 是否真的在現行 index—— 在→只補 content_hash 不打 AI;不在→重置 is_embedded=0 交回正常 backfill 佇列。 - 新增 kbdb/tests/embed-backfill.test.ts(改走真 SQLite,比舊版手刻假 DB 更硬): 14 個測試涵蓋新到舊排序、額度真的擋(含「拿掉 cap 會變紅」的反向驗證)、 世代核對端到端(reconcile → 重置 → backfill 真的補回來)、既有行為不迴歸。 現況誠實回報:目前沒有任何東西會自動觸發補算(無 cron/scheduled handler)—— 唯一的「自動」路徑是 entries.ts 的語意搜尋回 0 命中時 fire-and-forget 觸發一次 (既有行為,本次未改動),仍需人或 CC 主動呼叫 /embed/backfill 或掛排程。 紅線:未動 leo 正式實例 leo21c;未動資料層形狀(三表不變,仍走既有 content_hash bookkeeping 欄);未 push main,本 commit 在獨立分支 fix/embed-backfill-d68。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>