docs(spec): artifact-sharing 審查對齊 ×2 — K2 改 KBDB 唯一公庫後端(對齊 #16)+ 零件界線照 #23/D29

審查意見兩處(總管 2026-07-07):
1. K2 原「recipe 維持 KV 公庫、泛化端點 front 兩後端」與 #16(RECIPES KV→KBDB)衝突
   → 改為 KBDB 是唯一公庫後端;#16 落地前對 type=recipe 的 KV 轉接明定為過渡碼、
   #16 完成即拆(1.5/5.2 對應改);KV 公庫不得寫成穩態。遷移本體=#16 負責,不重工。
2. component 界線照 #23/D29 定案改:零件貢獻整層搬到獨立 repo Leo/arcrun-components
   (fork→PR→人審);市場只偵測缺件→引導去該 repo 開 PR,永不傳輸/安裝零件程式;
   arcrun_publish_component 路徑廢除。design/requirements/tasks 凡提零件發布處照此改。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015d5jDbuqT5Htwv3Q88XXKk
This commit is contained in:
Leo
2026-07-07 09:09:37 +00:00
parent 7777414b70
commit 1d7f69215a
3 changed files with 20 additions and 20 deletions
@@ -30,7 +30,7 @@
- 安全與審核設計(app-store 市場信任 vs 零件 PR 閘的分界)。
### 不包含(Out of Scope
- 零件安裝(PR 路徑,另案);credential 分享;跨環境市場聚合層;recipe 從 KV 遷 KBDBSaaS/api-key。(詳 requirements Out of Scope。)
- 零件安裝(`Leo/arcrun-components` fork→PR→人審路徑,另案);credential 分享;跨環境市場聚合層;recipe 從 KV 遷 KBDB 的**執行**#16 負責;本 SDD 只以「KBDB 唯一公庫後端」為前提設計)SaaS/api-key。(詳 requirements Out of Scope。)
---
@@ -51,7 +51,7 @@
│ 自己 namespace(私庫) │ │ materialize adapter(型別化落地) │
│ workflow → WEBHOOKS KV+KBDB │◄───────│ workflow → push (/webhooks/named) │
│ template → KBDB /templates │ │ template → create_template │
│ recipe → RECIPES KV │ │ recipe → installRecipeRecord │
│ recipe → RECIPES(→KBDB#16) │ │ recipe → installRecipeRecord │
└──────────────────────────────┘ │ + 依賴解析(遞迴 pull / 引導) │
└─────────────────────────────────────┘
```
@@ -63,7 +63,7 @@
| 決策 | 選擇 | 原因 | 放棄的選項 |
|------|------|------|----------|
| **K1 端點:泛化一套 vs 每型別一套** | **泛化一套 `/public-artifacts?type=` 讀,型別化 adapter 寫** | 讀側(搜/列/取全文/market_stat/落空引導)三型邏輯完全同構,泛化成一套省 3×重複、給 AI 一致心智模型(low-code);寫側(materialize 落自己 namespace)三型的家不同,必須型別化 | ❌ 每型一套 `/public-workflows`+`/public-templates`(3× 複製 recipe 端點,維護面爆、AI 要記三套);❌ 全泛化含寫(做不到,落地各異) |
| **K2 公庫儲存後端** | **workflow/template 公庫建在 KBDB**`entry_type=public_artifact`**recipe 維持既有 KV 公庫**、泛化端點 front 兩者 | 對齊儲存鐵律(長效→KBDB)+白拿 KBDB 語意搜尋(Vectorize embedworkflow-discovery 已證);recipe KV 公庫已上線穩定,重寫=在可用機制上重投資(mistakes 教訓) | ❌ 全部塞 KV(違鐵律、無語意搜尋);❌ 逼 recipe 立刻遷 KBDB(負 ROI,列未來選項 |
| **K2 公庫儲存後端** | **KBDB 是唯一公庫後端**`entry_type=public_artifact`。workflow/template 一開始就建在 KBDBrecipe 公庫隨 **#16RECIPES KV→KBDB 遷移)**收斂進同一後端。過渡期(#16 落地前)泛化端點可暫時把 `type=recipe` 轉呼既有 KV 路徑,但 **KV 公庫=過渡態、非穩態**#16 完成即拆轉接 | 對齊儲存鐵律(長效→KBDB)+白拿 KBDB 語意搜尋(Vectorize embedworkflow-discovery 已證);#16 同向不打架——遷移本體由 #16 負責,本 SDD 不對 KV 公庫做任何新投資 | ❌ 全部塞 KV(違鐵律、無語意搜尋);❌ 把「KV 公庫 front 兩後端」寫成穩態(與 #16 衝突,雙後端維護面永久化);❌ 本 SDD 自己動手遷 recipe(與 #16 重工 |
| **K3 身份模型** | **沿用 recipe UUID 身份模型**uuid=身份、canonical_id/author/type=屬性、submit-p=新增作者版本不覆蓋、per-uuid market_stat | 已被 recipe 驗證(kbdb-base §7.5.5);三型共用同一套,pull「選市場最佳作者版本」邏輯可共享 | ❌ 為 workflow/template 另設身份模型(分裂、無法共用選版邏輯) |
| **K4 依賴傳輸邊界** | **recipe/template 隨 workflow 一起 pullcomponent 只偵測引導、credential 只列清單** | component 是程式=攻擊面,鎖 PR 路徑(#23);credential 是機密,永不可攜(鐵律) | ❌ export 內嵌 component 程式(把 PR 閘繞掉,重演 #23);❌ export 內嵌 credential 值(機密外洩) |
| **K5 審核閘** | **資料 artifact 無 submit 前置人閘**(市場信任),**信任判斷點移到 import 時**(市場數據+依賴清單+外呼檢查) | leo 2026-06-29 已對 recipe 移除 exposure_consent 閘(arcrun 給 AI 用);資料 artifact 不在 host 上跑任意碼,風險≠零件 | ❌ 對 submit 加人類 consent 閘(與 recipe 已定案反向、增摩擦);❌ 完全無信任訊號(import 端沒判斷依據) |
@@ -109,7 +109,7 @@ export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)
- `GET /public-artifacts/:type/:canonical_id?author=` — 取單一全文(pull 用)。多作者→選 `market_stat.success_count` 最高版本(沿用 recipe 選版邏輯)。落空→創作引導。
- `POST /public-artifacts/submit` — 投稿(submit-p)。body 帶 `{ type, canonical_id, portable_body, dependency_manifest, author, stat? }`。**領新 uuid = 新增作者版本**(不覆蓋,§7.5.5);`stat` 只寫 `*_submission` 存證 entry,不併真實計數。
> **recipe 相容**泛化端點內部對 `type=recipe` 轉呼既有 KV 公庫路徑(`listAllRecipes`/`installRecipeRecord`,對 `type=workflow|template` 走 KBDB `public_artifact` 路徑。對外一套 API,對內兩後端(K2)。可先只上 workflow/templaterecipe 沿用既有 `/public-recipes`(見 tasks 分期)。
> **recipe 相容(過渡)**:終態=三型都走 KBDB `public_artifact` 路徑(K2KBDB 唯一公庫後端)。#16RECIPES KV→KBDB)落地前的過渡期,泛化端點對 `type=recipe` 暫時轉呼既有 KV 公庫路徑(`listAllRecipes`/`installRecipeRecord`——這段轉接碼是**過渡碼**#16 完成後 `type=recipe` 走 KBDB、轉接即拆,不留雙後端。可先只上 workflow/templaterecipe 沿用既有 `/public-recipes`(見 tasks 分期)。
### 導入語意 + materialize adapterR4
@@ -130,7 +130,7 @@ export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)
|---|---|---|---|
| **recipe** | workflow `config``component: rec_xxx` / http_request 引用的 canonical_id | **遞迴 co-pull**:對每個 recipe canonical_id 走 `pull('recipe', …)` 寫進自己私庫。有界遞迴(recipe 通常不再引用其他 artifact;設深度上限防環) | recipe 是資料,同屬「資料庫就能完成」,一起帶走才可跑 |
| **template** | workflow 若寫 KBDB record(引用某 template name | **co-pull**template 不存在→`pull('template', …)`→create_template | 同上;template 是 slots 宣告,可攜 |
| **component(零件/code** | workflow `flow:` cypher 用到的 builtin 零件(`http_request`/`code`/`cron`…) | **只偵測不安裝**:對照本部署 `acr parts`component registry。齊→放行;缺→回報「此 workflow 需零件 X,你的部署沒有。零件走 PR→併 main→部署安裝(`arcrun-components` repo),非 pull」。用 §7.5.6 式引導**絕不自動抓程式** | 零件是程式=攻擊面, PR 閘(#23、component-gatekeeping)。這是本 SDD 與零件案的**界線落點** |
| **component(零件/code** | workflow `flow:` cypher 用到的 builtin 零件(`http_request`/`code`/`cron`…) | **只偵測缺口→引導開 PR,永不傳輸/安裝零件程式**:對照本部署 `acr parts`。齊→放行;缺→回報「此 workflow 需零件 X,你的部署沒有。零件貢獻已整層搬到獨立 repo **`Leo/arcrun-components`**fork→PR→人審→併 main→隨部署/更新安裝),非 pull」。用 §7.5.6 式引導 | 零件是程式=攻擊面,唯一入口=`Leo/arcrun-components` PR 人審閘(#23/D29 定案;`arcrun_publish_component` 路徑已廢除)。這是本 SDD 與零件案的**界線落點** |
| **credential** | recipe 的 `credentials_required[].key` / workflow `{{credential.xxx}}` | **只列清單引導**:彙總所有需要的 key,回報「請 `acr creds push` 填:notion_token, …」。**值永不隨 artifact 傳輸** | 機密鐵律:值存 CF Worker Secrets,可攜檔只帶 key 名 |
- **dependency_manifest** 在 **export/submit 時就算好並存進 record**(掃 portable_body 抽引用),import 端不必反解 workflow 內部結構就能預覽「這東西會拉進哪些 recipe/template、需要哪些零件與 credential」——也是 import 的**信任預覽面**K5)。
@@ -138,7 +138,7 @@ export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)
### 安全與審核(R7 / K5)—— 對照 Arcrun#23 教訓
- **#23 教訓**`publish_component` 零人閘(提交即 active/public + MCP 全域)=攻擊面。結構解已定:**廢 MCP 發布路徑、零件投稿唯一入口=PR**(`arcrun-components`
- **#23 教訓#23/D29 定案**`publish_component` 零人閘(提交即 active/public + MCP 全域)=攻擊面。結構解已定**`arcrun_publish_component` 路徑廢除**;**零件貢獻整層搬到獨立 repo `Leo/arcrun-components`,唯一入口=fork→PR→人審**。市場/artifact 分享機制只做「缺件偵測→引導去該 repo 開 PR」,**永不傳輸、永不安裝零件程式**
- **本 SDD 的分界**:資料 artifactrecipe/workflow/template**不是**零件那種攻擊面——它們是宣告式資料,pull 進來只會**執行預先審過的零件**、只會打 recipe 指定的 endpoint、只會用 template 的 slots。故:
1. **submit 無前置人閘**app-store 市場信任,沿用 leo 2026-06-29 對 recipe 移除 consent 的拍板)。壞版本靠市場數據淘汰,不靠事前審。
2. **信任判斷點在 import 時**,用三個既有訊號:① `market_stat`(真實使用成功率,per-uuid);② `dependency_manifest`(import 前預覽「會拉哪些依賴、打哪些 endpoint、要哪些 credential」);③ **`data-exfil-warning` 外呼檢查**(該 SDD 的 API 層:recipe endpoint 域名異常時警示)——pull 進來的 recipe 依賴同樣過這層。
@@ -158,10 +158,10 @@ export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)
### 資料模型
- 公庫 recordKBDB `public_artifact` entry(見上)。**不建新表**entry_type + metadata_json 承載,KBDB 鐵律)。
- 公庫 recordKBDB `public_artifact` entry(見上)**KBDB 是唯一公庫後端**(K2;recipe 過渡期例外見上)。**不建新表**entry_type + metadata_json 承載,KBDB 鐵律)。
- market_stat:復用既有 KBDB recipe-statskey=uuid,型別無關)。
- 存證:`artifact_submission` entry。
- 私庫落地:沿用各型既有儲存(workflow=WEBHOOKS KV+KBDB 雙寫、template=KBDB /templates、recipe=RECIPES KV),**不改**
- 私庫落地:沿用各型既有儲存(workflow=WEBHOOKS KV+KBDB 雙寫、template=KBDB /templates、recipe=RECIPES——現為 KV**隨 #16 遷 KBDB**),本 SDD **不改**私庫儲存、materialize adapter 打各型既有寫入 API 故遷移對本 SDD 透明
---
@@ -190,7 +190,7 @@ export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)
## 相關文件
- `arcrun/kbdb-base/design.md` §7.5recipe app-store / 公私庫雙向 / UUID 身份)— 本 SDD 的母範本。
- `component-gatekeeping/``arcrun-components` repo — 零件走 PR 的界線另一側。
- `component-gatekeeping/`獨立 repo **`Leo/arcrun-components`**#23/D29:零件貢獻整層外移,fork→PR→人審)— 零件界線另一側。
- `workflow-discovery/` — workflow 已雙寫 KBDB + 語意搜尋,本 SDD 的公庫搜尋基礎。
- `data-exfil-warning/` — import 時外呼信任檢查層。
- `4-guides/arcrun-primer.md`InkStoneCo 頂層)— A/B 兩類工作、紅線。
@@ -200,7 +200,7 @@ export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)
## 待 leo / richblack 拍板的設計點
1. **K2**recipe 公庫是否收斂到 KBDB(與 workflow/template 同後端),或永久維持 KV 雙後端?本 SDD 預設「不動 recipe、泛化端點 front 兩後端」,收斂列未來選項
1. ~~**K2**recipe 公庫是否收斂到 KBDB~~ **已定(審查 2026-07-07,對齊 #16**KBDB 是唯一公庫後端,recipe 隨 #16 收斂;KV 只是 #16 落地前的過渡轉接,不是穩態。剩餘協調點只有「轉接拆除時機跟 #16 進度對齊」
2. **export 預設格式**YAML(對齊 workflow.yamlvs JSON。本 SDD 預設 YAML、兩者皆支援。
3. **MCP/CLI 命名**:型別化措辭(`acr workflow pull`vs 泛化措辭(`acr artifact pull --type=`)。本 SDD 建議型別化對外、泛化對內。
4. **依賴遞迴深度上限**:建議 5,是否合適。