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

154 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/kbdb`D1 三表 + CRUD API),**不在這裡、不動它**。
> **本目錄專屬交棒見 `docs/HANDOFF-kbdb-plugin.md`**SDD 見 `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-17****0 份 active**(無現行開發,實作面已收斂、剩跨 repo 接通)——0 份 active 合法。三份 `paused`ingest-contract / kbdb-graph-extraction / plugin-install,等基本盤部署/跨 repo 接通),兩份 `closed` 入 `archive/`。**重啟開發時先挑一份升 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 嗎?」
```bash
grep -rin "<本題關鍵字>" system-dev/wiki/
```
**三條硬規則**
1. **wiki 與程式碼/歷史文件衝突 → 以 wiki 為準**。程式碼反映「還沒清乾淨」,不等於「還在用」。
2. wiki 寫「不可動/待廢除/進行中」→ **讀它的解除條件並逐條核對**。那是當時狀態,不是永久禁令。
3. 翻原文後得到新結論 → **回頭更新 wiki**wiki 過時是債,要還)。
**動外部系統(部署/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.md`SDD 在 `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 API`KBDB_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.sh`AI 照跑;參考 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.vars`gitignore**不進版控**)寫 `KBDB_BASE_URL=http://localhost:8787` |
**為何不用 .env**:這是 CF Workerwrangler 本地讀 `.dev.vars` 不是 `.env`。本地測試值→`.dev.vars`;部署→`wrangler secret`;toml 只留空占位。三者各司其職。