Files
kbdb-graph-plugin/CLAUDE.md
T
Leo 2cb9d19442 docs: CLAUDE.md 加「第一鐵律:wiki 是判準,不准跳過」
leo 2026-07-21:「其他 repos 各自都要警覺不能跳過 wiki」。
hook 只是提醒,鐵律要寫在本 repo AI 開工必讀的地方。
含 grep 查法、三條硬規則、動外部系統前先找現成腳本(別自創方法)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 10:55:41 +08:00

9.8 KiB
Raw Blame History

CLAUDE.md — KBDB-graph 插件開發規範

上游約束(InkStoneCo 總管):此目錄(原 matrix/kbdb,已改名 kbdb-graph-plugin)是 InkStoneCo 子專案,受頂層知識庫約束。 動工前讀 github.com/uncle6me-web/InkStoneCo 的 CLAUDE.md + docs/3-specs/matrix-rearrange/定位(leo 2026-06-13:此 repo = KBDB-graph 插件triplet 採集 + graph 查詢),類比 Apache AGE 之於 Postgres。基本盤 = arcrun/kbdbD1 三表 + CRUD API),不在這裡、不動它本目錄專屬交棒見 docs/HANDOFF-kbdb-plugin.mdSDD 見 system-dev/docs/3-specs/2026-07-17 已從舊 docs/3-specs/ 遷移統一)。

本檔案由 Claude Code 自動讀取。所有在此目錄下的開發必須遵守以下規則。


📐 SDD 生命週期鐵律(leo 2026-07-17 拍板,全文見 system-dev/docs/3-specs/SDD-LIFECYCLE.md

  1. 單一活性:任何時刻整個 repo 最多一份 status: active 的 SDD,所有開發任務唯一對應它的 tasks;找不到對應任務 → 停下來問,不准直接做。
  2. 禁止自行建立 SDD:澄清問題→回答不動文件;任務層變更→更新現行 SDD 的 tasks(標日期原因);規格層變更→走第 3 條。
  3. 規格變更只有一條路proposal 寫進 system-dev/docs/3-specs/pending-changes.md(摘要+原因+影響分析)→ 停止等使用者「confirm」。
  4. 開新 SDD 的唯一時機confirm 後——先把舊 SDD 未完成任務逐條搬入新 SDD(做完前不准寫 code)→ 舊的標 closed + superseded_by 移入 archive/ → 列搬移/作廢清單請最終確認。
  5. 每次 session 開始:讀 active SDD 與 pending-changes.md,回報三個數字(現行規格〈名稱〉/未完成任務 N/待裁決 proposal M)。

本 repo 現況(2026-07-170 份 active(無現行開發,實作面已收斂、剩跨 repo 接通)——0 份 active 合法。三份 pausedingest-contract / kbdb-graph-extraction / plugin-install,等基本盤部署/跨 repo 接通),兩份 closedarchive/重啟開發時先挑一份升 active(一份、只能一份),再動 code——sdd-guard hook 會擋 0-active 下的 code 寫入。


🔒 KBDB 鐵律(leo 2026-06-14 拍板,最高原則,違反會被 hook exit 2 擋下)

決策全文:InkStoneCo/docs/3-specs/matrix-rearrange/DECISION-kbdb-v3-baseplane.md

  1. 任何人不准動表 — 禁 CREATE/ALTER/DROP TABLE。那 3 表只有基本盤維護者(leo)能改。
  2. 插件不准直接接觸表 — 禁 SELECT/INSERT/UPDATE/DELETE、禁 JOIN、禁 .prepare(...sql...)、禁綁 D1/Vectorize/AI。
  3. 讀寫全走基本盤 API/CLI/MCP — 插件與 AI/人同一條路(薄殼原則)。base URL = KBDB_BASE_URL env var。
  4. 新資料類型 = 建 template + 填 slot,永不建表 — triplet=template='triplet'、entity=template='entity',走 POST /templates+POST /records
  5. 零 migration、零 SQL — 插件目錄無 migrations/。SQL 只存在於基本盤 worker 內部。

比 AGE-on-Postgres 更嚴:AGE 能讀 Postgres 表,KBDB 插件連表都不許碰,必須透過基本盤 API。真正的 API-as-Wall。 誠實限制:hook 擋語法層明顯 SQL;藏在 helper 裡的繞道擋不了 → 文檔(本檔)+ hook 都不可省。想到「建表」時只准 template/slot。

掛載架構

基本盤 arcrun/kbdb(不動)          KBDB-graph 插件(本 repo
─ entries / templates / entry_values   ─ triplet template 定義 + graph 查詢函式
─ CRUD API:                            ─ 寫 triplet → POST /records (template=triplet)
   POST /entries  POST /templates       ─ 查圖 → GET /records/by-template/triplet
   POST /records  GET /entries/search          → 插件層【記憶體】組鄰接表跑圖演算法
   GET /records/by-template/:tpl       ─ entity 正規化 → template='entity'exact match
                                       ─ 唯一對外通道 = src/lib/kbdb-client.ts

基本盤 API 契約詳見 system-dev/docs/3-specs/kbdb-graph-extraction/design.md基本盤缺口base 無 PUT/DELETE /records/:id、無 vectorize 語意搜尋)標 [→arcrun],不得為此自建表。embedding/語意搜尋屬基本盤 optional embed 模組,不是插件職責


🔴 第一鐵律:wiki 是判準,不准跳過(2026-07-20/21 leo 兩度點破)

要查任何東西之前,先搜尋 wiki——用 grep,不是只讀開頭幾行。

leo:「花很多力氣去產生 wiki,最重要的就是要可以查詢,結果要查的時候就跳過,那就白寫了。」 「重點是你自己的記憶對嗎?而你有按照規定去切實讀 wiki 嗎?」

grep -rin "<本題關鍵字>" system-dev/wiki/

三條硬規則

  1. wiki 與程式碼/歷史文件衝突 → 以 wiki 為準。程式碼反映「還沒清乾淨」,不等於「還在用」。
  2. wiki 寫「不可動/待廢除/進行中」→ 讀它的解除條件並逐條核對。那是當時狀態,不是永久禁令。
  3. 翻原文後得到新結論 → 回頭更新 wikiwiki 過時是債,要還)。

動外部系統(部署/curlwrangleracrgh)前:先找 repo 有沒有現成腳本或 README 部署段, 別自創方法。(實例:2026-07-21 明明有 npx wrangler deploy 這條驗過的路,卻自己 curl 硬幹踩坑。)

hook wiki-first-search.sh 會在你查 code/下高風險指令時自動推 wiki 命中行; 但機制只是提醒,判斷是你的責任

Wiki 讀取順序(LLM 記憶系統,CC 維護)

檔案 時機 用途
system-dev/wiki/status.md session 開始第一件事 當前進度、下一步
system-dev/wiki/mistakes.md 做新功能前 已知誤解、避坑清單
system-dev/wiki/decisions-summary.md 設計判斷時 架構決策摘要

文件分類規則見 docs/README.mdSDD 在 system-dev/docs/3-specs/[子系統]/design.md + tasks.md),動手前必須有這兩個檔案,且遵守上方生命週期鐵律。 session 結束用 /wiki-update 更新 status.md,被糾正後 /wiki-capture 寫進 mistakes.md。


樂高法硬性限制(Layer 1

  • src/actions/ 目錄下的檔案嚴禁超過 100 行,建議 50-80 行
  • 一檔一事:每個 action 只做一件具體的事
  • 無狀態:Action 不保存記憶體狀態,所有狀態透過參數傳遞或走基本盤 API 持久化(不碰 D1/Vectorize
  • Route 檔案(src/routes/不含業務邏輯,僅驗證參數 + makeKbdbClient(c.env) + 呼叫 action

目錄結構

src/
├── lib/          ← kbdb-client.ts(唯一對外 API 通道)、templates.ts(插件 template 定義)
├── actions/      ← 核心業務邏輯(純函數,< 100 行,第一參數收 KbdbClient
├── routes/       ← HTTP 入口(Hono route,只做驗證 + 呼叫 action
├── types.ts      ← 型別定義(= contracts
└── index.ts      ← Worker 進入點(只掛 triplets/graph/entities/search 路由)

開發流程

  1. types.ts 定義輸入/輸出型別
  2. tests/ 寫測試(走 tests/mock-client.ts 的 mock KbdbClient,不打真網路)
  3. actions/ 實作邏輯(透過 KbdbClient 讀寫,零 SQL
  4. routes/ 建立 HTTP 入口

技術棧

  • Framework: HonoOpenAPIHono
  • 資料層: 全走基本盤 arcrun/kbdb HTTP APIKBDB_BASE_URL)。插件本身無 D1/Vectorize/AI 綁定。
  • Validation: Zod
  • Testing: Vitest(純 node + mock client
  • 部署: wrangler 直推 Cloudflare不開 Actions(避免再被 flag,見頂層鐵律)

2026-06-14:按 leo 鐵律改寫完成。21 個違規直接 SQL action 全改走基本盤 API;刪除所有 migrations(插件零建表);移除 D1/Vectorize/AI 綁定。基本盤規範歸 arcrun/kbdb


安裝與 KBDB_BASE_URL(安裝契約,leo 2026-06-14

KBDB_BASE_URL 由「安裝時的 AI」自動填,不是人填。 wrangler.toml"",因為它因部署而異(每個 self-hosted 用戶的 workers.dev subdomain 不同)。值不寫死、不叫人填、不放 .env。

URL 是確定性的,AI 必然查得到

  • URL = https://arcrun-kbdb.<subdomain>.workers.dev
  • arcrun-kbdb 固定(基本盤 worker name);<subdomain> 用 CF API GET /accounts/{id}/workers/subdomain 查(用戶已登入 wrangler → 查得到)。
  • 「能 deploy 就能查 URL」deploy 與查 subdomain 用同一套 CF 憑證,不存在「能裝卻查不到」。
  • 一律連 workers.dev(預設),不要求用戶自訂域名(自訂是進階選項,非安裝必填 → 安裝時不問人)。

安裝流程(scripts/install.shAI 照跑;參考 arcrun docs/3-specs/arcrun/sdk-and-website/self-hosted-init.md

用戶給 github 網址 → AI

  1. wrangler whoami → account_id(已登入用戶 CF
  2. GET /accounts/{id}/workers/subdomain → 拼基本盤 URL
  3. wrangler secret put KBDB_BASE_URL(部署)— 不寫進 git
  4. wrangler deploy 插件 → 用戶全程零填寫、零 toml、零 .env

測試的 base URL(兩層,分開放)

測試 base URL 放哪
單元測試 tests/*.test.ts 不需(走 tests/mock-client.ts,不打網路) KBDB_BASE_URL 留空照跑。日常主力。
整合測試(驗證打通基本盤) 本地起基本盤:cd ../arcrun/kbdb && wrangler dev(如 http://localhost:8787 .dev.varsgitignore不進版控)寫 KBDB_BASE_URL=http://localhost:8787

為何不用 .env:這是 CF Workerwrangler 本地讀 .dev.vars 不是 .env。本地測試值→.dev.vars;部署→wrangler secrettoml 只留空占位。三者各司其職。