Files
kbdb-graph-plugin/contracts
Leo e7a681a989 fix(ingest): receiver Zod 追上 contract — 補向量化打標欄位 (issue #1 補對齊)
契約漂移修補:T3 的 strict Zod 鏡射舊 contract,ingest 照新 contract(ingest#1
升格)送向量化打標欄位會被 .strict() 擋成 422。方向 A:顯式加合法新欄位、保留
strict。

- 同步 contracts/ingest-candidate.json 副本到頂層單一真相源(mira-dissolve)。
- NodeSchema 加 id?/aliases?/embed?;EdgeSchema 加 predicate_embed?。strict() 保留
  → bridge_score/clusters 等 graph 領域禁送欄位仍 422。
- 落地:predicate_embed 透傳進 triplet slot;node 打標(embed/gloss/aliases)存進
  entity slot,供 base/KBDB embed 模組讀標執行(graph 不算向量,鐵律一致)。
- id 作 node 去重鍵:同卡多邊指到只存一筆 entity。
- persistNodes 拆成獨立 action(triplet-ingest.ts 回到 95 行,守樂高 100 行限制)。
- 測試 +4:帶向量化欄位通過、bridge_score/clusters 仍 422、同 id 去重。
  vitest 23 passed。零 SQL / 無 D1·Vectorize·AI 綁定 / dry-run 乾淨。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 20:23:40 +08:00
..

contracts/ — graph 插件邊界契約

本目錄放 graph 插件對外的 JSON Schema 契約。兩份契約是不同方向的東西,別混

兩份契約的分工

檔案 是什麼 方向 誰產 / 誰收
ingest-candidate.json 輸入候選envelope ingest 插件 graph 插件 ingest 萃取後送進來,graph 收下處理
triplet.json 已存三元組graph 內部存的單筆 S-P-O graph 內部 / 對查詢面 graph 寫進基本盤 records 後的形態

核心區別ingest-candidate 是「還沒進庫的一批原始萃取」,triplet 是「已經正規化、存好、可查的單筆」。

  • ingest 只送原始 (subject, predicate, object) + confidence禁送 graph 領域欄位(id / clusters / bridge_score / created_at / triplet 上的 *_entity_type)。送了 → graph 以 422 拒收(additionalProperties: false)。
  • 正規化、clusters、bridge_score、embed、status/superseded_by 取代邏輯——全是 graph 領域ingest 一無所知(純餵食器)。

ingest-candidate envelope 重點

  • 一個 envelope = 一個來源檔(canonical MD)一次萃取的產物
  • source.uri(穩定識別)+ source.content_hash(快照鍵)共同決定 idempotency
    • 同 uri + 同 hash → no-op{skipped:true})。
    • 同 uri + 新 hash → deprecate-then-append(舊 active 翻 status=deprecated + superseded_byappend 新批 active)。
  • nodes[](選填)帶 gloss / entity_type —— 節點屬性,不是邊屬性,故獨立於 triplets[]。graph 用 gloss 去 embed(每節點一句,非裸詞)。

完整 schema 與欄位說明見 ingest-candidate.jsondescription / $comment。 本 repo 對此契約的實作(端點、取代邏輯、測試)見 docs/3-specs/ingest-contract/