Files
Arcrun/registry/examples/km-wiki-ingest/DEPLOY.md
T
kbdb-cc c6932b0088 feat(km-wiki-ingest): 重做成跑在 cypher 上的 workflow(走 cypher binding,汰換 service-binding drainer,D28)
把知識庫 ingest 從 standalone drainer(誤用 Service Bindings)重表達為 cypher workflow:

- workflow.yaml(Phase 0 cron drain):watch_cron→load_cursor→list_cards→pick_card(code)
  →fetch_card→parse_card(code)→upsert_entry→save_cursor→post_envelopes→post_one_envelope。
  線性 pipe,跨-worker 全走 cypher binding(零件節點),零 service binding。
- workflow.delta.yaml(Gitea webhook 穩態):collect_changed(code)→foreach card→fetch/parse/upsert/foreach envelope。
- code/kbdb/graph 接法:code=canonical `code` 零件(arcrun-code);kbdb/graph=http_request 零件打
  /entries/ingest、/triplets/ingest(server 端冪等);Gitea=http_request。
- 平台端最小補丁(各需 gated 部署):
  1) cypher-executor component-loader:WASM_HTTP_RUNNER_IDS 加 'code'(canonical→arcrun-code,cypher binding 正解)。
  2) kbdb base:POST /entries/ingest(page_name+content_hash 冪等 upsert,對稱 graph /triplets/ingest;
     因 flow DSL 無資料條件分支,把 create/patch/skip 冪等推到 server 端)。
- drainer/DEPRECATED.md:標舊 standalone worker 退役計畫(新版穩定後 wrangler delete)。
- DEPLOY.md:部署順序、cron/webhook 掛法、subdomain 對齊、驗收與退役。

本輪不部署(待總管/leo 審架構)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJiLCRUU2o3aSpPEzVCt2o
2026-07-06 12:59:13 +00:00

104 lines
5.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.
# km-wiki-ingest — 部署(cypher workflow 版,走 cypher binding
> **架構(D28**:知識庫 ingest **跑在 cypher-executor 上的 workflow**,跨-worker 呼叫全走
> **cypher binding**(零件節點,由 component-loader 解析),**零 Service Bindings**。
> 汰換舊的 standalone `arcrun-km-wiki-drainer``drainer/`,已誤用 service binding → 見 `drainer/DEPRECATED.md`)。
>
> **本輪不部署**(等總管/leo 審架構)。以下是過閘後的部署順序。
## 0) 先決條件(兩個平台端小改,皆本分支已含,需各自 gated 部署)
這兩處是「讓 workflow 能純走 cypher binding」的最小平台補丁,**不是** ingest 專屬邏輯:
1. **cypher-executor`code` 零件進 loader 白名單**
- 檔:`cypher-executor/src/lib/component-loader.ts``WASM_HTTP_RUNNER_IDS``'code'`(本分支已加 1 行)。
- 效果:workflow 節點 `component: code` → 解析成 `arcrun-code.{WORKER_SUBDOMAIN}.workers.dev`cypher binding)。
- 部署:`cd cypher-executor && npx wrangler deploy`(要 leo 過閘;動到共用 executor)。
- **替代(不改 executor**:把兩個 workflow 裡 `component: code` 改成 code 的完整 URL
`component: "https://arcrun-code.<subdomain>.workers.dev"`(走 loader step 2 外部 URL)。省一次 executor 部署,
但少了「canonical 零件」的乾淨語義。建議用白名單版(這才是 D28 說的 cypher binding)。
2. **KBDB base`POST /entries/ingest`server 端冪等 upsert**
- 檔:`kbdb/src/routes/entries.ts`(本分支已加)。語義對稱 graph 的 `/triplets/ingest`
page_name 當鍵、`content_hash` 同 → skip、不同/無 → update、無則 create。
- 為何需要它:cypher 的 flow DSL **無資料條件分支**(只有 ON_SUCCESS/ON_FAIL/FOREACH),
無法在 workflow 內做「查→比對→create 或 patch」三岔。把冪等推到 server 端,workflow 只打一發。
- 部署:`cd kbdb && npx wrangler deploy`(要過閘)。
> ⚠️ **subdomain 對齊**:兩個 workflow 內的 URL 用 `uncle6-me`(官方 `WORKER_SUBDOMAIN`,見 `cypher-executor/wrangler.toml`)。
> 若你的 arcrun-kbdb / kbdb-graph-plugin / arcrun-code 部在別的 workers.dev subdomain(例 `leo21c`),
> 把兩檔的 URL 一起改。**舊 standalone drainer 誤用 `leo21c` 是坑之一。**
## 1) CLI 設定
```bash
# self-hostednamespace 明碼分區):
acr config set mode self-hosted
acr config set cypher_url https://cypher.arcrun.dev # 或你自架的 executor
echo "NAMESPACE=leo" >> .env
# standard(平台多租戶):acr init 取 api_key
```
## 2) 設 Gitea token(機密;節點以 {{credential.gitea_token}} 引用)
```bash
acr creds set gitea_token <你的 GITEA_TOKEN> # 讀 Leo/notes 用
```
> graph 的 `X-Arcrun-API-Key: leo` 是 namespace 字串(非機密),已內嵌節點,不需設 credential。
## 3) 部署 Phase 0 draincron 觸發)
```bash
acr push workflow.yaml
```
- `watch_cron``cron_expr: "*/2 * * * *"` 會被 `webhooks-named``extractCronExpr` 抓出,
寫進 `cron-idx:_all`cypher `scheduled()` 每分鐘比對觸發本 workflow**不需另設 CF cron**)。
- 游標**不需 seed**:首跑 `load_cursor` GET 回空 → `pick_card` 從頭;`save_cursor` 首 tick 自動 create。
- 手動補跑一 tick(驗收):`acr run km_wiki_ingest_drain`
## 4) 部署穩態 deltaGitea webhook 觸發)
```bash
acr push workflow.delta.yaml
```
- 取得 trigger URLself-hosted 例):
`https://cypher.arcrun.dev/webhooks/named/leo/km_wiki_ingest_delta/trigger`
- Gitea repo `Leo/notes`**Settings → Webhooks → Add Webhook → Gitea**
- Target URL:上面的 trigger URL
- Content-Type`application/json`
- TriggerPush events
- standard 模式改帶 `X-Arcrun-API-Key` headerself-hosted 免 headernamespace 在 path
- 這是 Gitea→Cloudflare(cypher)**非 GitHub Actions** → 不觸 GitHub flagD4/D20)。
## 5) 驗收
```bash
# entry 落地?
curl -s "https://arcrun-kbdb.uncle6-me.workers.dev/entries?owner_id=leo&entry_type=wiki_card&limit=5" | jq '.count'
# triplet 落地?
curl -s "https://kbdb-graph-plugin.uncle6-me.workers.dev/graph?owner_id=leo" | jq '.nodes|length'
# 游標?
curl -s "https://arcrun-kbdb.uncle6-me.workers.dev/entries?owner_id=leo&page_name=cursor:km_wiki_ingest_drain:Leo/notes" | jq '.entries[0].content'
```
冪等自證:連跑兩次 `acr run km_wiki_ingest_drain`,第二次同卡 entry `action:skipped`、graph per-source no-op。
## 6) 舊 standalone drainer 退役
- 全 drain 完 + delta webhook 穩定收斂後,退役 `arcrun-km-wiki-drainer``wrangler delete arcrun-km-wiki-drainer`
- 保留 `drainer/` 原始碼一個週期(含 `DEPRECATED.md`)供對照,確認新版逐卡輸出與舊版一致再刪。
-`drainer/DEPRECATED.md`
## 節點圖速覽
**draincron**`watch_cron(cron)``load_cursor(http GET kbdb)``list_cards(http GET Gitea tree)`
`pick_card(code)``fetch_card(http GET Gitea raw)``parse_card(code)`
`upsert_entry(http POST kbdb /entries/ingest)``save_cursor(http POST kbdb /entries/ingest)`
`post_envelopes(foreach)``post_one_envelope(http POST graph /triplets/ingest)`
**deltawebhook**`collect_changed(code)` →〔對每個 card〕→ `fetch_card_d``parse_card_d(code)`
`upsert_entry_d(http)``post_envelopes_d(foreach)``post_one_envelope_d(http)`
零件對應的 cypher binding`code`→arcrun-code`http_request`→arcrun-http-request(打 Gitea/kbdb/graph);
`cron`→觸發登記;`foreach_control`→平台 logic primitive(唯一允許的 service-binding 用法:零件等級,非本工作流編排)。
**全程無工作流等級的 service binding。**