uncle6me-web
|
9344562258
|
feat(kbdb): embed 自我檢查端點(檢修孔第一塊,2026-08-07 leo 直接指令)
GET /embed/selftest?owner_id= —— 挑一筆已標記「已嵌入」的卡片,拿它自己的內容做一次
真實語義查詢,檢查「自己是否搜得到自己」。backfillStatus 的 pending/embedded 計數
看不出 Arcrun#11 那種「嵌了但查不到」的故障模式(metadata index 事後才建、既有向量
沒被收錄),本端點是唯一能端到端驗證 index 真的可用的方法。
隱私邊界:只回 {enabled, tested, passed, note} 四個布林/字串欄位,不回卡片內容、
不回 entry id(測試 embed-selftest.test.ts 最後一案專門斷言不洩漏)。
12/12 kbdb vitest 全綠(含既有 embed-backfill 6 案未壞)。
|
2026-08-07 18:35:06 +08:00 |
|
uncle6me-web
|
7ba78552a4
|
D38:credential 目錄改走 KBDB API(零原生 SQL)+舊表退場;測試刻意留紅燈
存取層:credentials.ts / auth-dispatcher.ts / portal.ts 全改走 kbdbBase()+fetch
到 /entries(照 execution-logger.ts 既有慣例),.prepare/.exec/.batch 命中 0。
資料層:0005 seed credential template;0006 把舊表資料搬進 entries 後拆表;
0002 標退役、deploy.ts 不再套用(加 kbdb-sql-ok 留痕,純歷史對照)。
總管親驗四項(不聽 agent 自評):
1 三個檔 .prepare/.exec/.batch 命中 0;六個檔全部通過 kbdb-api-wall-guard
2 0006 的 INSERT 欄位(id/entry_type/owner_id/page_name/metadata_json/
created_at/updated_at)與 0001_base 的 entries 表逐一對得上
3 不可逆風險查官方:D1 batch 是 transaction、任一句失敗整批 rollback;
exec 出錯則「執行停止、後續不執行」=> 兩種語意下 INSERT 失敗都不會跑到
DROP TABLE,用戶 credential 目錄不會遺失
4 0006 搬在拆之前、冪等(NOT EXISTS 防重複)、豁免標記有留痕且理由正當
(拆表是牆內施工,API 不提供也不該提供拆表)
🔴 抓到一個假綠並修正:agent 中途被中斷,把 111 行的 credentials.test.ts
砍成一行「// placeholder — see edit below」,那個 edit 從來沒發生,
且 setup.ts 被刪。vitest 對這種檔案回報「Tests: no tests」,
很容易被讀成「沒失敗=通過」——正是 CP 記過的
「這條 route 曾整條消失過沒人發現」同型。
處置:還原 setup.ts/vitest.config.ts,credentials.test.ts 改成
**刻意會失敗的紅燈**並在檔頭列出要補的五項。空檔會被誤認為綠,紅燈不會。
未部署。本批要先上 stage 驗過才進 prod(leo 08-07 定)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 17:27:18 +08:00 |
|
uncle6me-web
|
60688c3108
|
fix(kv-quota): workflow 執行紀錄搬離 KV,改走 KBDB template 機制(A1/A2/A7)
事故:cypher-executor/src/actions/execution-logger.ts 舊版每跑完一次 workflow 就
ANALYTICS_KV.put() 一筆新 key(註解寫「避免覆蓋」)= 只增不減,封測者 Evan 處理約 690 個
檔案就把 KV 免費層 1,000 write/日打爆(實測 1,070 write),整個實例 429。
A1 少記:workflow 執行紀錄改走 KBDB template 機制(entries 表 entry_type='execution_log',
kbdb/migrations/0004_execution_log_template.sql 只 seed 一列 template 定義,零建表/改表)。
儲存精神比照既有 recipe_stat(kbdb/src/actions/recipe-stat.ts):template 只負責文件化,
實際一筆執行是 entries 表一列(1 次執行=1 次 D1 寫入,不走 entry_values 全展開)。欄位收斂:
時間/workflow/verdict/duration/錯誤訊息/(可得的)目標;成功記最少,失敗多記(訊息截斷長度
不對稱:200 vs 2000 字)。target 只認 trigger context 的 page_name/path,不整包存 input。
A2 自我降級:D1 額度仍與知識卡共用同一顆 100,000 rows/日,本模組自設 20% 軟上限(可用
EXECUTION_LOG_DAILY_WRITE_LIMIT 覆寫),超過 80% 降成只記失敗、超過 100% 完全停止記錄,
但 workflow 執行永遠照跑(cypher-executor 端 fire-and-forget 永不 throw)。
A7 讀取端:/workflows/:name/executions、/portal/data/workflows 的 last_execution、MCP
list_recent_executions 全部改打 KBDB HTTP API(GET /execution-log、/execution-log/latest),
取代原本的 ANALYTICS_KV list/get(免費層 list 也是 1,000/日)。
架構鐵律修正(本次施工中兩度被抓到走偏,過程留痕於 commit 訊息供後續參考):
- KBDB 三張表打天下(entries/templates/entry_values),永遠不加新 table——新資料類型
一律用 template + entries,不建表、不 ALTER TABLE。
- KBDB = API-as-Wall,零 SQL:cypher-executor 端一律走 KBDB 的 HTTP API(連法比照既有
recordRecipeStats/kbdbFetch 慣例),不直連任何 D1、不對 arcrun-kbdb 下任何原生 SQL。
順帶修復:kbdb/src/actions/entry-crud.ts listEntries 的 ORDER BY 補 `, rowid DESC` 二級
排序——entries.created_at 是 unixepoch() 秒級解析度,高頻寫入(execution_log 一秒內多筆)
常同秒,單靠 created_at DESC 不保證「最新一筆」正確,此為本次測試(latestExecutionLog)
發現的既有潛在缺陷,順手補上決定性排序,不改變任何既有查詢在 created_at 不同時的行為。
隔離:portal-data.ts INTERNAL_ENTRY_TYPES 加入 execution_log/execution_log_usage(與既有
value/workflow 同層級排除),避免用戶知識搜尋混進執行 log;本模組從不設 metadata_json.embed,
故永不進 Vectorize 語意搜尋索引。
不動:registry/src/actions/recordAnalytics.ts(零件市場統計,獨立 Worker、獨立 KV 命名空間、
不同資料模型,非本次事故根因所指範圍);cypher-executor/{wrangler.toml,kbdb/wrangler.toml}
未變動(repo 層級 deny 規則保護這兩個生產設定檔不被 AI 編輯)——ANALYTICS_KV binding
因此仍留在 wrangler.toml 宣告中但程式碼零讀寫點(見 PR 說明的完整 grep 佐證)。
KV 裡既有的 stats:* 舊資料不搬移(是統計不是真相源,維持原樣任其依 90 天 TTL 自然過期)。
測試:kbdb/tests/execution-log.test.ts(13 個,含零建表證明/少記/A2 降級/route)、
cypher-executor/tests/execution-logger.test.ts(payload 正確性/永不 throw)、
cypher-executor/tests/executions-route.test.ts(讀取端轉發)、portal-data.test.ts 對應區塊
改寫。kbdb 全測試 104/104 通過;cypher-executor 320 個測試中 9 個失敗為 main 既有(與本次
改動無關,改動前後 stash 對照確認)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-07 16:13:00 +08:00 |
|
uncle6me-web
|
05b215c9f7
|
語意門檻改相對式+下架連帶刪向量(leo 兩個實測回饋)
## ① 「關懷型 AI 命中 20 筆、只有前 3 筆相關」⇒ 閾值太寬(leo 判斷正確)
固定門檻兩頭都不對,因為每個查詢的分數尺度不同(實測 youlin 實例):
關懷型 AI 正解 0.645-0.770,雜訊起於 0.547 ← 固定 0.5 放進 6 筆雜訊
閉環機 正解 0.552-0.638,雜訊起於 0.446 ← 固定 0.6 砍到剩 2/4(=早上的 0 命中)
人力媒合系統規劃書 正解 0.842,雜訊起於 0.550
⇒ 改**相對門檻** max(0.45, top×0.8)。五組實測:固定 0.5 混入 9 筆雜訊/
固定 0.6 有兩組正解被砍/相對式四組雜訊 0 且正解全留。
## 🔴 寫測試才發現的真問題:門檻不能在 Vectorize 那層算
Vectorize 的 indexed metadata 沒有 status ⇒ 那層不知道誰已下架。
若最高分是下架殘影(t24 復現案 0.971),拿它算門檻=0.777,
會把 0.6 的正解一起砍光 ⇒ **又變成 0 命中**。
⇒ 相對門檻移到 routes/entries.ts,接在「hydrate+濾下架」之後;
embed.ts 只留絕對下限。新增測試鎖住這個順序。
## ② leo:「理論上它的向量也要刪掉,就不會有殘影了吧?」——對,補上
單筆真刪已接 deleteByIds(b7af622),但「移除整個庫」走軟刪、向量原地不動。
⇒ deprecate-by-library 同時 deleteByIds + is_embedded 歸零(D1 與 Vectorize 不說兩套話);
backfill 兩條路徑(含 reindex)都排除 deprecated,否則下次補嵌會把殘影養回來。
不違背 t135「資料保留可還原」:D1 那列原封不動,還原後跑 backfill 重嵌即可。
回應新增 vectors_deleted,刪失敗誠實回 0 不假裝清乾淨。
驗:kbdb 91/91 綠(新增 4 項相對門檻測試,含「下架殘影不得決定門檻」)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-05 18:47:10 +08:00 |
|
uncle6me-web
|
0ff369f818
|
修語意搜尋全 0 命中:分數門檻沒跟著 bge-m3 換代(換模型漏掉的第五處)
leo 2026-08-05 實撞:「新上傳的『loop-engine-north-star.md』語義 0 命中,
但舊的『人力媒合系統規劃書』語義 2 命中」。
## 根因不在向量——向量是好的
直打 Vectorize 實測(youlin 實例、bge-m3、1024 維 index):
搜「閉環機」→ loop-engine-north-star.md 穩坐第 1-4 名(0.638/0.603/0.588/0.552)
D1 與 Vectorize 也對得上:659 筆 embeddable 全 is_embedded=1、index vectorCount 659。
真兇是 **min_score 門檻綁在舊模型的分數尺度上**:
舊 bge-base-en-v1.5:中文分數全擠 0.65-0.90(沒區辨力)⇒ t183 取 0.75 砍雜訊,對
新 bge-m3 :尺度整體下移(相關 0.5-0.85、雜訊 0.4 上下)⇒ 0.75 砍掉的是正解
leo 看到的「舊檔中、新檔不中」由此而來——「人力媒合系統規劃書」拿 0.842 僥倖存活,
其餘全被門檻掃掉。08-05 換 bge-m3 的「四處同步」清單(embed.ts/deploy.ts/
deploy-all.mjs/worker.js)**漏了這第五處**,因為它不在 kbdb 而在 portal 呼叫端。
## 改動
· kbdb/src/embed.ts:新增 DEFAULT_MIN_SCORE=0.5,**緊鄰 DEFAULT_EMBED_MODEL**
——門檻是模型的性質,放模型旁邊,下次換模型的人一定會看到
· cypher-executor/src/routes/portal-data.ts:拿掉硬寫的 0.75,
只在使用者顯式指定時才傳 min_score(不再各自持有一份數字=不再漂移)
· console-ui/public/portal/os-split.test.mjs:修好被今天 fe0ee82 弄壞的自測
(結尾標記寫死文案 ⇒ 改文案就炸「抽不到函式區塊」;改成錨定結構)
+斷言同步改成 Mac 給 DMG
## 0.5 怎麼來的(實測分布,不是猜的)
「閉環機」 0.638/0.603/0.588/0.552 全是目標檔 ── 斷崖 ── 0.446 才是雜訊
「火星座標 奧林帕斯山」 0.750…0.500 全對,0.475 以下才是雜訊
「人力媒合系統規劃書」 0.842 對,0.550 起是雜訊
誠實 trade-off:0.5 非每個查詢都乾淨(「AI 上課名冊」0.658 的 ax-academy 會擠進來),
但「偶有雜訊」遠優於現況「什麼都搜不到」。
## 驗
· kbdb 87/87 綠(三筆斷言隨新契約更新:預設不再是「不過濾」)
· cypher-executor 9 failed/301 passed=**與改動前逐數相同**(git stash 前後各跑一次)⇒ 既有債
· portal os-split 自測 10/10 綠
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-05 18:00:43 +08:00 |
|
uncle6me-web
|
b9b5d98d75
|
併 bge-m3 換代(#59)+補上分支漏做的另一半:Vectorize index 也換
leo 2026-08-05:「換 embed model 當然要合併,當然要換 vectorize,**原本的根本不能用**」
——我把已拍板的事當成待裁決,錯了。
## 為什麼非換不可(08-03 leo 拍板,5 組中文測資實證)
@cf/baai/bge-base-en-v1.5 768 排序正確 2/5 margin -0.0413 1660ms ← 舊
@cf/baai/bge-m3 1024 5/5 +0.1410 959ms ← 新
舊英文模型嵌中文:分數全擠在 0.65-0.81,區辨力接近沒有=**根本不能用**。
## 🔴 分支只做了一半,另一半我補上
feat/embed-model-m3-t59 只改 kbdb(embed.ts / types.ts / 測試),**完全沒動 deploy.ts**
⇒ 就算合併,安裝器仍會建 **768 維的舊 index**,新向量根本收不進去。
(git show f3af5d3 --stat 實查:只有 3 個檔,全在 kbdb/)
本次補上安裝器那半:
· KBDB_VECTORIZE_INDEX: arcrun-kbdb-embed → **arcrun-kbdb-embed-m3**(換名字,非只換維度)
· ensureVectorizeIndex: dimensions 768 → **1024**
· kbdb/wrangler.toml 說明與 metadata-index 指令同步改新名(照抄不會建錯 index)
· embed.ts docstring「768 維向量」→ 1024(分支漏改,會誤導)
## 為什麼要換「名字」不是只改維度
① 維度 768→1024,舊 index 收不進新向量
② 就算維度相同也不能沿用——不同模型的向量混在同一 index 比對出來是垃圾,
而 #58(Vectorize vector delete 未接)代表舊向量刪不掉
⇒ **開新名字反而順手繞開 #58**,且新舊並存可回滾。
## 查證(歷史警察 Q0-Q3,非假設)
· git log --all -S"arcrun-kbdb-embed-m3" / -S"dimensions: 1024" 皆空 ⇒ 無分支改過,非重造輪子
· **metadata index 用同一個常數**(deploy.ts:426 ensureVectorizeMetadataIndexes)
⇒ t36 的四個 metadata index(owner_id/entry_type/source/library,Arcrun#11 根因修復)
會自動建在新 index 上,**不會因改名而遺失**——這點特地查過,不是假設。
## 驗
· kbdb 測試 87/87 綠(含新增 4 項 embed-model-config)
· cli tsc --noEmit **零錯誤**
· 三處一致性機械確認:embed.ts=bge-m3/deploy.ts=dimensions 1024/index=arcrun-kbdb-embed-m3
· 踩到並記錄:註解寫 `**dimensions=1024**/metric` 會因 `*/` 提早關掉 block comment(TS1127)
## 既有實例遷移(尚未執行,需對實例操作)
建新 index → 重部署 kbdb(binding 指新 index)
→ POST /embed/backfill {"reindex":true} 到 remaining=0 → 舊 index 可刪。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-05 13:46:33 +08:00 |
|
Leo
|
f3af5d3631
|
feat(#59): embed 模型可配置,預設換成 bge-m3——英文模型嵌中文會排錯
leo 2026-08-03 拍板「換 m3」。#59 本體(模型應可配置+index 版本化)。
## 為什麼換:實測,不是憑感覺
5 組中文問答測資(每組 1 問 + 2 段相關 + 3 段無關,無關的刻意放同一知識庫裡的其他主題),
margin = min(相關分數) − max(無關分數),margin ≤ 0 代表排序是錯的:
@cf/baai/bge-base-en-v1.5 768 排序正確 2/5 平均 margin -0.0413 1660ms ← 舊
@cf/google/embeddinggemma-300m 768 4/5 +0.1275 1174ms
@cf/baai/bge-m3 1024 5/5 +0.1410 959ms ← 新(最好且最快)
@cf/qwen/qwen3-embedding-0.6b 1024 4/5 +0.1381 3238ms
最刺眼的一組:問「知識庫問答為什麼要標出處?」→「會議室預約規則」0.7789
竟然高於真正相關的 0.7306。這正是 leo 2026-07-18 回報的「問 RAG 卻引用會議室規範」,
過去只被描述成「semantic 排名近乎雜訊」,其實是**排序錯誤**,而且五組錯三組。
英文 bge 系列的分數全擠在 0.65-0.81(區辨力接近沒有)——中文對它就是看不懂的 token。
## 改動
- `EMBED_MODEL` 常數 → `DEFAULT_EMBED_MODEL='@cf/baai/bge-m3'` + `embedModel(env)`,
可由 `env.EMBED_MODEL` 覆寫(#59 要的「可配置」),空字串/空白視為沒設。
- 寫入端(embedOnWrite / backfill)與查詢端(semanticSearch)共用同一個 getter
——兩邊不同步是最惡毒的 bug:不報錯、分數全垃圾、外面完全看不出來。已加測試守。
## 換代必須換 index(安裝器那半在 arcrun-rag 同名分支)
① 維度 768→1024,舊 index 收不進新向量
② 就算維度一樣也不能沿用——不同模型的向量混在同一個 index 比對出來是垃圾,
而 #58(Vectorize vector delete 未接)代表舊向量刪不掉
⇒ 開新 index 反而順手繞開 #58。
既有實例遷移:建新 index → 重部署 kbdb(binding 指新 index)
→ POST /embed/backfill {reindex:true} 重嵌到 remaining=0 → 舊 index 可刪。
驗證:kbdb 全套 87/87 綠(含新增 4 項);tsc 與基線相同(只剩既有的 auth.test.ts 那筆);
打包實跑產物 grep:kbdb bundle 只有 @cf/baai/bge-m3、舊英文模型 0 殘留。
|
2026-08-03 03:48:28 +00:00 |
|
Leo
|
47c6aaea03
|
feat(t152): workers_ai_chat 種子(auth: binding,免金鑰)+ 修 /init/seed 吃掉 3.12 欄位+ 修 D1 LIKE 長查詢 500
SDD: workflow-discovery 3.12/3.13(不是新規格;3.12 已 confirmed 並實作完成)
## 1) workers_ai_chat 種子(新)
Cloudflare Workers AI 走 env.AI binding ⇒ 用戶不必填任何 API 金鑰就能問答。
放種子表而非產品安裝器:「裝好後預設有哪些 recipe」是平台能力(rule 07 薄殼原則)。
換模型/換供應商=改這一筆 recipe,workflow 不動。
選型實測(1.4.4 實例,真實長度 RAG prompt,每個模型連跑 2 次):
llama-4-scout-17b 2373/2173 ms ✅ 答案最完整、引用正確 ← 選它
llama-3.3-70b-fp8-fast 3261/2147 ms ✅ 可用但波動較大
mistral-small-3.1-24b 3560/3631 ms
qwen2.5-coder-32b 3572/3353 ms
gpt-oss-120b 1971/2295 ms ❌ 回應形狀不同,response 取不到文字
gemma-3-12b-it ❌ 5018 帳號無權限
對照舊路徑 Gemini gemma-4-31b-it:同型提問 16.87 s,且吐整段英文思考草稿。
## 2) 修 /init/seed 靜默吃掉 3.12 欄位
3.12 給 RecipeDefinition 加了 body_template/response_map/auth/binding_name,
但 /init/seed 是**列舉欄位重建** recipe record ⇒ 不在名單上的欄位被丟掉。
最惡劣的地方是「哪裡都不會紅」:recipe 查得到、endpoint 對,只有跑起來像沒設定過。
與 08-02 syncManifest 吃掉 manifest.daemon 欄同型(教訓:東西還在不在也要進機械閘)。
加 tests/init-seed-recipe-fields.test.ts:拿掉修復會紅、補回會綠(已實測會擋)。
## 3) 修 D1 LIKE pattern 50 bytes 上限造成的 500
/entries/search?q=… 只要 q 超過 48 bytes 就回 HTTP 500,沒有錯誤訊息。
逐 byte 二分:48→200/49→500;中文 16 字→200/17 字→500。
判別實驗:q 固定 48 bytes、其他 filter 全塞滿讓 SQL 變很長 → 仍 200
⇒ 爆的是 LIKE 的 pattern('%'+q+'%' = 50),不是 statement 長度。
中文問句超過 16 字是常態,而 rag_chat 用整句問題當 q ⇒ 聊天對正常問句等於不能用。
(=InkStoneCo status.md 待辦第 1 條「KBDB keyword 長查詢會炸」的根因。)
修法:q ≤ 48 bytes 走原路(行為逐字不變),超過才拆詞/切 UTF-8 邊界片段。
kbdb 全套 83 測全綠(含新增 8 項)。
## 4) 順手
- 移除被 commit 進 repo 的 node_modules 壞 symlink(指向 leo Mac 的絕對路徑,
害任何 fresh clone 裝不起來、切分支還會把裝好的蓋掉——本次撞了兩次)。
- pending-changes.md 加 P2 提案(fan-out 並行執行)+等裁決,未動引擎。
驗證:cypher-executor 新增測試 17/17 綠;tsc 與基線逐字相同;
全套測試失敗集合與基線**逐字相同**(基線 14 個失敗,本分支 t173 既有,非本次引入)。
|
2026-08-03 02:56:53 +00:00 |
|
Leo
|
5b983c47b8
|
Merge branch 'main' into fix/merge-main-into-batch-t173
# Conflicts:
# console-ui/public/portal/index.html
# cypher-executor/src/routes/health.ts
# cypher-executor/src/routes/portal.ts
# registry/components/kbdb_upsert_block/component.contract.yaml
# registry/examples/km-wiki-ingest/workflow.yaml
|
2026-08-02 23:43:16 +08:00 |
|
Leo
|
e28e19069f
|
t142: 雲端子庫顯示同步幾張卡+幾個三元組(政府專案驗收需求)
leo 07-29:「要在雲端子庫顯示同步了幾個 wiki,既然這樣也同步顯示有幾個三元組,
這是為了政府專案驗收。」
kbdb 兩支統計端點:
- entries.ts: COUNT(DISTINCT page_name) AS card_count
⚠️ 必須 distinct——算 block 數會膨脹 3-5 倍,政府驗收看到假數字比沒數字更糟
- records.ts: COUNT(*) AS triplet_count(三元組本來就算全部)
portal.ts 聚合兩者掛進庫目錄;前端 index.html 顯示。
驗:卡數確為 COUNT(DISTINCT page_name)/前端內嵌 JS node --check 全通過
(07-29 白畫面事故教訓)/portal-admin 測試 34 passed(改動前 31 passed,
唯一的 1 failed 是既有債:GET /portal 回 404,改動前後相同,非本次造成)。
註:此為子 CC 完成後未 commit 的懸置工作,總管收工檢查時發現並補收。
|
2026-07-29 19:55:03 +08:00 |
|
uncle6me-web
|
0860e84d22
|
feat(t135): 庫目錄可自主移除+標示還在不在同步
leo:「需要加移除按鈕。因為別人裝錯我沒辦法幫他弄,需要可以自主」
+「你應該要顯示這個庫沒有本地對應的 folder,那就不容易刪錯」
(兩態非三態——leo 二修:「分兩種沒意義」,那是內部狀態不是用戶分類)。
- DELETE /portal/admin/libraries/:id(登記簿)與 by-name/:name(auto 庫需輸入庫名確認)
- kbdb 加 deprecate-by-library(auto 庫移除=標 deprecated,資料保留可還原)
- daemon/libraries 存 active 清單 → 卡片標 🟢同步中/灰目前沒有在同步
- 不自動刪(daemon 可能沒開機);daemon 從未回報時整列不標
vitest 24 passed(1 紅=console HTML 搬遷陳舊測試,非本案)。
(實作=子 CC;驗證+commit=總管。含 t116/t117 先前未 commit 的 graph-executor/wasi-shim 修正)
|
2026-07-29 14:45:44 +08:00 |
|
uncle6me-web
|
f6728974ea
|
fix(t115 🔴🔴🔴 三修): kbdb 認證完全 fail-closed——沒金鑰一律 401(含讀取)
leo 實證的洞=「知道網址即可讀走全部知識」;一修 fail-open(沒設 secret 就不擋)、
二修仍放行讀取=洞沒補。三修(總管手改):無 token→全部 401(health 豁免),
老實例升級路徑=重跑安裝器(同時注入金鑰與新 workflow),不以繼續外洩換相容。
+結構閘測試:斷言 src/index.ts 的無 token 分支不得有 return next()——
擋「測試複本與真實作漂移」那類假綠(本輪正是它抓到二修的複本沒同步)。
kbdb vitest 60/60 全綠(總管親跑)。
|
2026-07-28 23:52:43 +08:00 |
|
uncle6me-web
|
139d4c5ed1
|
feat(t52): 資料夾=庫端到端——kbdb 加 /entries/libraries(資料面 distinct 庫);portal 庫目錄合併「登記簿+蓋章自動出現」(auto);auto 庫改安全渲染(無 record_id 不放死按鈕,改給『登記到目錄』)+daemon/libraries 自動登記端點。leo 07-26:地端 2 個資料夾雲端就要 2 個庫
|
2026-07-26 01:49:43 +08:00 |
|
uncle6me-web
|
dd78b770a9
|
fix(kbdb): /entries/search 服務端濾 deprecated(keyword+semantic),修下架不生效
daemon-beta t24(t11 斷點①②,總管 0.971 親復現):rag_takedown_direct 下架只把
metadata_json.status 標 deprecated(軟刪,append-only),但 /entries/search 兩 mode
都不濾,已下架內容照樣回傳——semantic 甚至最高分照吐。過去唯一的濾層只在
cypher-executor/portal-data.ts 客端(Arcrun#46),沒部署 rag_chat 的實例等於完全沒濾。
- entry-crud.ts:新增 json_extract($.status) NOT_DEPRECATED_PREDICATE(同 source/library
既有 json_extract 模式,issue #5.1/#18;不用 LIKE 避免 JSON 序列化格式誤判);
searchEntries 新增 includeDeprecated 參數(尾端新增,向後相容)。
新增 isDeprecatedEntry:semantic 路徑用(Vectorize metadata 沒存 status,只能 hydrate
回完整 entry 後 JS 側判斷)。
- entries.ts:/entries/search 新增 include_deprecated 開關(預設 false,濾掉;true 給
管理面查殘留)。semantic 分支補位——過濾生效時先以 topK×3(封頂 100)向 Vectorize
多撈,hydrate+濾完再截斷回 caller 要求的量,避免命中大半下架時整頁被吃光
(t11 ZZ-T10 實測案例)。
- Vectorize 向量殘留本 PR 不動(只做查詢時過濾,not 同步刪向量)——取捨見 PR 描述。
測試:新增 search-deprecated-filter.test.ts 15 案(keyword 濾/include_deprecated 開關/
semantic 濾+補位+封頂+截斷/isDeprecatedEntry 單元);同步更新 search-source-and-score.test.ts
3 案的 topK 期望值(route 補位改變送進 Vectorize 的實際 topK,回應對外契約不變)。
kbdb 全套 60/60 綠、tsc --noEmit 乾淨。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
2026-07-24 16:35:17 +08:00 |
|
Claude
|
15fe012006
|
feat(kbdb): 藏書地圖 M1+M2 — library_map template+/map 端點(聚合 SQL 住基本盤)(#39)
M1:library_map template(migration 0003 seed+runtime ensure,D6 零建表零 ALTER);
核實 triplet 按庫定位=不足(prod triplet template 無 library slot、entries
metadata.library 未標記)→ 走 SDD 預案:recompute 冪等補 optional library slot
(改 template 不動表),slot 值由 ingest 端(M3)補寫,核實結果記入 design §1。
M2:kbdb base 三端點(design §2 歸屬裁定:聚合 SQL 只准住基本盤):
- POST /map/recompute?library=X:degree top-N/predicate 分布/跨庫 bridges/
triplet_count 一段 SQL 聚合;narrative 本輪收 body 傳入(wiki 抽取屬 M3);
寫入順序安全(先建新 active map block 再標舊 superseded,讀端取最新 active 自癒);
過渡 source_prefix fallback 讓無 library 值的舊 triplet 靠 source_uri 前綴歸庫。
- GET /map:全館地圖每庫一行(library+narrative+top 3 entities+triplet_count),
MCP instructions/GUI 共用(數百 token 內)。
- GET /map/:library:該庫詳圖(完整 slots+可嵌人話 content,design §5 M6 直用)。
測試:node:sqlite(零新依賴)當真 SQLite 實跑 migrations+聚合 SQL,
Hono route 行為同款覆蓋;45/45 過、tsc --noEmit 乾淨。
關聯 #39
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUmjwkHLVBHM3ydhT1WSW3
|
2026-07-19 08:40:22 +00:00 |
|
Claude
|
65d85eb08f
|
fix(kbdb): search keyword 補 source filter(#66)+semantic 曝 top_k/min_score 帶 score(#67)
#66:/entries/search keyword 路徑 source 解析後丟棄(#5.1 只接了 listEntries 那半)——
searchEntries 尾端加 source?(既有 positional caller 全不用改),conds 補與 listEntries
同款 json_extract(metadata_json,'$.source') 謂詞;route keyword 分支與 semantic 降級
分支兩處傳入。
#67:semantic 固定 topK=20、零分數閾值、低分尾硬湊數——route 曝 top_k(預設 20、封頂
100)與 min_score(預設 0=不過濾)query 參數;semanticSearch 依 min_score 截低分尾;
semantic 回應 entry 附 score 欄(加欄不改形)。壞值(非數字/非正)視同沒帶,不 400。
向後相容:不帶新參數時輸出與現況一致(semantic 僅多 score 資訊);不動表(D6)、
不動 D1 結構(API-as-Wall)。測試:新增 search-source-and-score.test.ts 13 條
(source 謂詞形狀/route 下傳/降級不洩 filter/min_score 截斷/topK 透傳封頂/壞值防呆/
不帶參數行為不變),kbdb vitest 33/33 綠、tsc 0。
關聯 #66 #67。merge 後需 gated redeploy kbdb worker(leo 閘)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUmjwkHLVBHM3ydhT1WSW3
|
2026-07-19 07:53:46 +00:00 |
|
Claude (總管雲端)
|
0ca3af4d1a
|
kbdb: searchByTemplate 修 N+1(100 筆 record 逐筆 getRecord ≈ 19 秒 → 批次 IN 查詢 1.3 秒)
leo 客戶測試「圖譜/AI 查詢 20-30 秒」的病根:by-template 列表對每筆 record
各跑一次 getRecord(每筆一次 D1 往返)。改為 record id 以 90 一組(D1 綁定
參數上限 100)批次 IN 撈 slot 值,輸出排序與形狀不變。
實測 uncle6:/records/by-template/triplet 19s→1.3s、portal 圖譜 20s→3s、
總圖 1.8s。kbdb 測試 20/20 綠、tsc 0。
|
2026-07-18 08:30:38 +00:00 |
|
Leo
|
1260d8cffb
|
portal-auth P2(#24 #25):portal_user 模型+認證 API(不 merge,待總管審) (#51)
|
2026-07-14 04:19:54 +00:00 |
|
Leo
|
7f409646e5
|
portal-auth P1(#24 #25):KBDB library filter 地基(不 merge,待總管審) (#50)
|
2026-07-14 03:50:06 +00:00 |
|
kbdb-cc
|
befc63cfe0
|
fix(kbdb/embed): 語意查詢 metadata 過濾根因修復(Arcrun#11)
根因:Vectorize index 建了卻從沒建 metadata index。CF Vectorize v2 要對某
metadata 欄位下 filter,必須先為該欄建 metadata index,否則帶 owner_id/
entry_type/source 過濾的語意查詢一律回 0 命中(app 端 filter 接線本來就對)。
且 metadata index 只索引「建立後 upsert」的向量 → 既有向量須重推才會被收錄。
- deploy.ts:加 ensureVectorizeMetadataIndexes(),隨部署冪等建 owner_id/
entry_type/source(string)三個 metadata index(self-host/官方帳號皆自動)。
- embed.ts / routes/embed.ts:backfillEmbeddings 加 reindex+offset,重推「所有
embeddable(含 is_embedded=1)」既有向量,讓事後建立的 metadata index 收錄;
POST /embed/backfill {"reindex":true} 觸發,offset 分頁到 remaining=0。
- wrangler.toml:註解補 create-metadata-index 手動步驟 + reindex 提示。
- tests:mock DB 對齊 LIMIT?/OFFSET? 與 reindex predicate;補 reindex 測試。
leo21c 已驗:owner_id=leo / entry_type 過濾修前 0→修後命中,不帶過濾不變。
已知後續(非本 bug 症狀):source 值 89-91 bytes 超過 Vectorize string
metadata index 的 64-byte 索引上限 → source 過濾對長值失效,另案。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJiLCRUU2o3aSpPEzVCt2o
|
2026-07-06 06:03:43 +00:00 |
|
Claude
|
55a47d7c18
|
kbdb(embed): add batch backfill endpoint for pre-Vectorize entries (issue #7 / T2.4 缺口)
embed 模組原本只有 embedOnWrite(寫入即嵌),對「開 Vectorize binding 之前就寫入」或
embed-on-write 當時漏掉的既有 entry 沒有回填路徑 → is_embedded=0 永遠補不回,語義查詢回 0 筆。
新增(base,對 entries 做;embedding 是 base 唯一職責,非 graph 插件):
- embed.ts: backfillEmbeddings()——找 is_embedded=0 且 isEmbeddable(metadata.embed===true) 的 entry,
批次補嵌(單次 AI.run 陣列 + 單次 VECTORIZE.upsert 陣列 + 單次 UPDATE IN,一批≈3 subrequest)、
設 is_embedded=1,冪等、分批(limit 1-100,回傳 processed/remaining,可重複呼叫直到清零)。
模組未開誠實回 enabled:false(不假綠)。backfillStatus() 回 pending/embedded 計數。
- routes/embed.ts: POST /embed/backfill、GET /embed/backfill/status;模組未開回 409 + capability_hint。
- index.ts: mount /embed。
- tests/embed-backfill.test.ts: 5 vitest(off no-op / 補嵌+標記 / 冪等 / 分批 remaining / status)。
base 維持對內容語意無知(只認通用 embed 旗標,不知 triplet/wiki)。tsc exit 0、vitest 5/5。
端到端(leo21c,wrangler 直推、非 acr update):pending 5→processed 5→remaining 0,
Vectorize vectorCount 0→5,/entries/search?mode=semantic 由 0 筆→5 筆(語義排序命中)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BDtnGPJpAzp8UqHfAo8o1s
|
2026-07-05 04:37:04 +00:00 |
|
Claude
|
f9dad311ff
|
feat(credential-store-migration): T2 D1 migration 0002_credentials.sql
新增 credentials 目錄表(api_key/name/service/sensitivity/secret_ref/
created_at/last_used_at,PRIMARY KEY(api_key,name) + idx_cred_apikey),
D19:只存目錄不存密文,密文本體改住 CF Workers per-script Secrets(T5)。
deploy.ts 重用既有 applyD1Migration,緊接 0001_base.sql 之後套用同一顆 D1,
機制完全一致(同一支 CF D1 query API)。
驗證:cli tsc --noEmit exit 0;leo21c arcrun-kbdb D1
(1099d0f3-d062-4202-984c-5a57b0a8c031)實際套用,
sqlite_master 確認 table+index 存在,重跑驗證冪等。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018D6QoC5waFkcjc2N7csJBB
|
2026-07-03 22:52:09 +00:00 |
|
Leo
|
9024f22534
|
fix(kbdb): entries list 端點加 q/search filter + 誠實 total 欄位 (Arcrun#3 發現①)
根因(CF D1 直查已核實):owner_id='leo' 租戶下 D1 實際有 458,357 筆,但
/kbdb/entries(list)從沒接過 search/q 參數——proxy 轉發白名單漏了它、base
listEntries() 也沒這個 filter,caller 帶 search= 會被靜默丟棄,永遠回「無過濾
list」。加上舊版 count 欄位=本頁筆數(非總數),容易被誤讀成「總共只有這幾筆」。
修法:
- kbdb/src/actions/entry-crud.ts:ListEntriesFilter 加 q,listEntries 回傳
{ entries, total }(total = 符合條件全部筆數,COUNT(*) 與 list 查詢並行跑)。
- kbdb/src/routes/entries.ts:GET / 讀 q 或 search(別名)當 LIKE filter,
回應同時帶 count(本頁)與 total(全部)。
- cypher-executor/src/routes/kbdb-proxy.ts:GET /kbdb/entries 轉發白名單加
q/search → 統一轉發成 base 認得的 q。
驗證見 issue #3 留言(CF D1 直查 + curl /kbdb/entries?search=遷移 有真實命中)。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
2026-07-03 08:51:29 +00:00 |
|
uncle6me-web
|
934b9265d9
|
feat: KBDB self-hosted 查詢 + embed 模組 + thin-shell 收窄 + search_workflow(code done 待端到端)
按 issue 分段標明(檔 #5/#8 改動交疊處無法乾淨拆檔,故併一個 commit):
#4 thin-shell §3.1 自力救濟階梯 + code-node 規則(純文檔/規則,code-node 零件未實作)
#5 KBDB source filter(json_extract metadata_json 零建表)+ 能力對照;documents 聚合與
DELETE proxy 部分擱置等頂層 T8
#7 base embed 模組(kbdb/src/embed.ts)+ vectorize 開關(deploy/config/wrangler.toml 註解範本)
+ 語義查詢降級閉環(mode=semantic 未開→LIKE+capability_hint)
#8 部分(workflow-discovery):
- KBDB /entries/search 加 base 通用 entry_type filter(entry-crud/embed/route/kbdb-proxy 透傳)
- /webhooks/named 強制 description(空→400,訊息要求操盤 AI 據實寫一句)
- 部署雙寫 entry_type=workflow embeddable entry(waitUntil 非阻塞,供 search)
- cypher GET /workflows/search + MCP u6u_search_workflows(優先語意、降級 hint)
- cypher POST /workflows/backfill-search-entries(無 desc 列出不編造)
- GET /webhooks/named 補回 description/created_at 欄位(為 list 來源收斂備)
⚠️ tsc 綠 = code done,非完成(mindset §7 禁假綠):
- #7/#8 端到端待 leo21c 部署驗(Vectorize 需官方憑證、CC 跑不了)
- #8 ①-a(MCP deploy 改打 /webhooks/named)未做、MCP deploy 那半仍 404
- #8 端到端(強制填擋空/語義命中/租戶隔離/降級 hint)未驗
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-27 17:52:52 +08:00 |
|
uncle6me-web
|
eeafd5c094
|
fix(kbdb): searchByTemplate 真按 owner_id 過濾(修租戶隔離洩漏)
煙霧測試發現 searchByTemplate 的 `if (rec && (!owner_id || true))` 是 stub,
`|| true` 讓 owner_id 過濾失效 → 任何租戶查同 template 看得到別人的 record。
改:給 owner_id 時 JOIN entries 在 SQL 限定 e.owner_id(record 歸屬存底層
entries.owner_id,createRecord 寫入時帶);沒給才不限(內部/全域查詢)。
cypher KBDB proxy 強制注入 owner_id,故端到端隔離靠這條 SQL 落地。
searchEntries 早已正確按 owner_id 過濾,無此 bug。kbdb tsc exit 0。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-14 22:18:17 +08:00 |
|
uncle6me-web
|
886a8e31d0
|
feat(kbdb,mcp): KBDB 資料層薄殼 + self-hosted MCP 認證 + cypher KBDB proxy
三件一條鏈(HANDOFF §2/§3b,kbdb-base Phase 9):
A. KBDB MCP 薄殼(9.1):mcp/src/tools/kbdb_data.ts 6 工具
template/record/query/search,調基本盤 API。鐵律:不給建表/SQL,只 template+slot。
B. MCP self-hosted 認證 401(mcp-account-source §5.5):
- partner-auth.ts:MULTI_TENANT=false 時 Bearer 明碼直接當 org_namespace,
繞 KBDB partner 驗證(對齊 cypher 的 opaque-key 模型)。官方 SaaS 行為不變、共用同碼。
- mcp-setup.ts:把 namespace/api_key 寫進 .mcp.json headers.Authorization。
- 新增 self-hosted vs SaaS 分支單測(9 tests 綠)。
C. cypher KBDB proxy(9.5)+ CLI 薄殼(9.2):
- routes/kbdb-proxy.ts 純轉發 /kbdb/* → KBDB 基本盤(KBDB_BASE_URL HTTP fetch,
不新增 service binding)。讓 CLI(只認證到 cypher)能達獨立 KBDB worker。
- 租戶隔離:X-Arcrun-API-Key 自動當 owner_id 注入 records/entries(強制覆寫防跨租戶);
templates 全域共享(虛擬表定義是 schema 非資料)。
- cli/src/commands/kbdb.ts:acr kbdb template/record/query/search,與 MCP kbdb_* 同能力。
- kbdb base:entries 加 page_name 過濾(9.3)。
cypher + cli + mcp tsc exit 0。未驗收:端到端需 deploy + KBDB_BASE_URL 可達後實測。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-14 22:12:32 +08:00 |
|
uncle6me-web
|
6e92ca0372
|
fix(self-hosted): acr update 10/23 部署失敗根因——pnpm 目錄補 commit pnpm-workspace.yaml(ERR_PNPM_IGNORED_BUILDS)+ CLI 失敗帶 stderr 尾段
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-12 23:25:46 +08:00 |
|
uncle6me-web
|
36d7492464
|
fix(kbdb): 填官方 prod D1 database_id(arcrun-kbdb)+ cli bump 1.3.2
kbdb/wrangler.toml placeholder → 官方 D1 id(self-hosted deploy.ts 注入會覆蓋,安全)。
deploy --all 時 cli 自動 bump 1.3.1→1.3.2 + CHANGELOG。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-07 16:34:30 +08:00 |
|
uncle6me-web
|
6a75117ba3
|
feat(kbdb): recipe 公庫/私庫雙向機制 + UUID 身份 + KBDB Base + 市場數據
kbdb-base SDD §7.5(公庫/私庫雙向機制,richblack 2026-06-07 拍板)。
## KBDB Base worker(新)
- kbdb/:D1-only 核心三表(entries/templates/entry_values)+ CRUD + LIKE search
+ recipe-stats 端點(市場數據)+ 0001_base.sql migration(含 recipe_stat seed)
## Phase 2.3:init 建 D1 + 套 migration
- cli cf-api.ts 加 listD1Databases/ensureD1Database;init 建 arcrun-kbdb D1
- deploy.ts 部署後對 D1 套 0001_base.sql(CF /d1/query API,idempotent)+ 注入 database_id
## Phase 5.1:recipe 成功記錄(市場數據來源)
- GraphExecutor 收集本次用到的 recipe uuid(usedRecipeKeys)
- executeWebhookGraph 執行結束一次性記 per-uuid 成功/失敗到 KBDB(fire-and-forget)
## Phase 7.5:recipe UUID 身份 + app-store 模型
- recipe 領 uuid=唯一身份;canonical_id/author/公私=屬性(§7.5.5)
- recipe:{uuid} + idx:canonical/installed/hash;resolveRecipe 向後相容不破執行鏈
- POST /recipes/submit=領新 uuid 新增作者版本(非覆蓋,app-store)
- GET /public-recipes 搜尋(多作者+per-uuid 市場星數)/ :id pull(選市場最佳)
- 落空→found:false 創作引導(§7.5.6 閉環)
- POST /recipes/migrate-uuid 一次性轉舊 key(增量寫不刪舊、冪等)
- init-seed 用 UUID(author=system)
## 薄殼(rule 07 §5:CLI + MCP 覆蓋同組能力)
- CLI: acr recipe search/pull/submit-p(config 加 DEFAULT_PUBLIC_LIBRARY_URL)
- MCP: arcrun_recipe_search/pull/submit_p/push/list/delete(補齊漂移)
## 壓測修正
- api-recipe-seeds: google_sheets_append PUT→POST(:append 正確動詞,階段12)
四 worker tsc 全綠(cypher/cli/kbdb/mcp)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-07 16:18:10 +08:00 |
|