3a1faf19f4
- decisions-summary.md:新增「KBDB 鐵律 + API-as-Wall」「安裝契約」; 修正過時兩條(「共用 D1 掛載」改 API;「萬物皆 Block v3」標已淘汰/違規殘留已刪) - 新增 ADR docs/2-architecture/decisions/0001-api-as-wall.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.7 KiB
2.7 KiB
ADR 0001:KBDB 鐵律 — 插件 API-as-Wall(零碰表 / 零 SQL / 零 migration)
- 狀態:已採納(Accepted)
- 日期:2026-06-14
- 決策者:leo(總管)
- 提出:KBDB-graph 子 repo CC
背景
KBDB-graph 插件(triplet 採集 + graph 查詢)原本直接以 SQL 讀寫基本盤的 blocks/entry_values 表(28×/31× SQL 引用),並帶獨立 blocks 表 + 0001/0005 CREATE TABLE migrations。子 repo 的 design.md 一度把這個「現狀」當成 AGE-on-Postgres 訊號,跑去問「要不要共用同一個 D1、直接 SQL 掛在基本盤表上」。
這是讀違規現狀去推翻鐵律——那些直接 SQL 是違反 API-as-Wall 的歷史產物,不是設計依據。
決策
KBDB 生態最高原則(leo 拍板):
- 任何人不准動表 — 禁
CREATE/ALTER/DROP TABLE。那 3 表(entries/templates/entry_values)只有基本盤維護者能改。 - 插件不准直接接觸表 — 禁
SELECT/INSERT/UPDATE/DELETE/JOIN、禁.prepare(...sql...)、禁綁 D1/Vectorize/AI。 - 讀寫全走基本盤 API/CLI/MCP — 插件與 AI/人同一條路(薄殼原則)。唯一通道 =
src/lib/kbdb-client.ts,指向KBDB_BASE_URL。 - 新資料類型 = 建 template + 填 slot,永不建表 — triplet=
template='triplet'、entity=template='entity'。連「插件自建獨立 D1(triplet_clusters 等)」都不行——那仍是建表。 - 零 migration、零 SQL — 插件目錄無
migrations/。SQL 只存在於基本盤 worker 內部。
比 AGE-on-Postgres 更嚴:AGE 插件能直接讀 Postgres 表;KBDB 插件連表都不許碰,必須透過基本盤 API。真正的 API-as-Wall。
後果
- 圖不靠 DB VIEW,靠插件層從 triplet records 在記憶體組鄰接表跑演算法。
- embedding / 語意搜尋屬基本盤 optional embed 模組(D1 only 之外的加購層),非插件職責;插件 entity 正規化降級 exact match、search 降級 keyword。
- 基本盤缺口(無
PUT/DELETE /records/:id、無 vectorize)標[→arcrun],不得為此自建表或直連 D1。 - 鐵律寫成 hook 強制(
.claude/hooks/pre-write-guard-no-table.sh、pre-bash-guard-no-table.sh,違反 exit 2)。誠實限制:hook 擋語法層明顯 SQL,藏在 helper 裡的繞道擋不了 → 文檔 + hook 兩者都不可省。
關鍵教訓
讀現狀 ≠ 設計依據。 違規代碼會自我合理化。現狀與鐵律衝突時,改現狀,不是改鐵律。
相關
- 頂層決策全文:
InkStoneCo/docs/3-specs/matrix-rearrange/DECISION-kbdb-v3-baseplane.md - 改寫範圍:
docs/3-specs/kbdb-graph-extraction/design.md、tasks.md(R-EXT-4) - 教訓:
.claude/wiki/mistakes.md「讀違規現狀推翻鐵律」