From 7777414b70543c257bd71a5d488232749c52a727 Mon Sep 17 00:00:00 2001 From: arcrun-subagent Date: Tue, 7 Jul 2026 08:13:27 +0000 Subject: [PATCH 1/2] =?UTF-8?q?docs(spec):=20artifact-sharing=20SDD=20?= =?UTF-8?q?=E2=80=94=20=E6=8A=8A=20recipe=20app-store=20=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=93=B4=E5=B1=95=E5=88=B0=20workflow/templa?= =?UTF-8?q?te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 規劃「資料庫就能完成的開發物」(recipe/workflow/template)的分享/發布/下載/導入/匯出。 泛化一套 /public-artifacts 讀端點 + 型別化 materialize adapter 寫;公庫存 KBDB; 依賴解析劃清界線(recipe/template co-pull、component 走 PR、credential 零傳輸)。 純文件,不改程式。 Co-Authored-By: Claude Opus 4.8 --- .../3-specs/arcrun/artifact-sharing/design.md | 207 ++++++++++++++++++ .../arcrun/artifact-sharing/requirements.md | 96 ++++++++ .../3-specs/arcrun/artifact-sharing/tasks.md | 124 +++++++++++ 3 files changed, 427 insertions(+) create mode 100644 system-dev/docs/3-specs/arcrun/artifact-sharing/design.md create mode 100644 system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md create mode 100644 system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md diff --git a/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md b/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md new file mode 100644 index 0000000..e06ca29 --- /dev/null +++ b/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md @@ -0,0 +1,207 @@ +# Artifact Sharing — Design + +> 狀態:草稿(待 review) +> 建立:2026-07-07 | 最後更新:2026-07-07 +> 負責人:Arcrun subagent(受 InkStoneCo 總管指派) + +--- + +## 一句話說明 + +把 recipe 的 app-store 公庫模型,泛化成「一套公庫 record 模型 + 一組泛化端點 + 三個型別化 materialize adapter」,讓 recipe / workflow / template 都能發布、搜尋、pull、export,並在 pull 時解析依賴。 + +--- + +## 背景與問題 + +見 requirements.md。核心:recipe 已有 `/public-recipes` + `submit` + `installRecipeRecord` 的完整範本(`cypher-executor/src/routes/recipes.ts`),workflow / template 缺這一整套。要複製它的**公私庫分界、UUID 身份、canonical_id/author、市場數據、pull=寫進自己私庫**這幾個成熟決策,而非重新發明。 + +--- + +## 範圍 + +### 包含(In Scope) +- 統一的公庫 record 資料模型(三型共用身份/市場欄位)。 +- 三型 artifact 的可攜格式(export)+依賴清單。 +- 公庫端點:泛化的 `/public-artifacts` 一套打通三型(見「關鍵決策 K1」的取捨與結論)。 +- 導入語意(pull)與型別化 materialize adapter。 +- 依賴解析(recipe/template 共 pull、component 引導 PR、credential 引導填值)。 +- MCP tools / CLI 命令三層對齊。 +- 安全與審核設計(app-store 市場信任 vs 零件 PR 閘的分界)。 + +### 不包含(Out of Scope) +- 零件安裝(PR 路徑,另案);credential 分享;跨環境市場聚合層;recipe 從 KV 遷 KBDB;SaaS/api-key。(詳 requirements Out of Scope。) + +--- + +## 設計 + +### 架構概覽 + +``` + ┌──────────────── 公庫(KBDB,長效資料)────────────────┐ + 發布 submit-p │ public_artifact entry(entry_type=public_artifact) │ 搜尋 / pull + ────────────► │ { uuid, type, canonical_id, author, portable_body, │ ◄──────────── + │ dependency_manifest, market_stat(per-uuid) } │ + └───────────────────────────────────────────────────────┘ + ▲ │ + (export 產可攜檔) │ │ pull = 取全文 + │ ▼ + ┌──────────────────────┴───────┐ ┌─────────────────────────────────────┐ + │ 自己 namespace(私庫) │ │ materialize adapter(型別化落地) │ + │ workflow → WEBHOOKS KV+KBDB │◄───────│ workflow → push (/webhooks/named) │ + │ template → KBDB /templates │ │ template → create_template │ + │ recipe → RECIPES KV │ │ recipe → installRecipeRecord │ + └──────────────────────────────┘ │ + 依賴解析(遞迴 pull / 引導) │ + └─────────────────────────────────────┘ +``` + +- **讀寫都走既有 worker**:公庫 record 存 KBDB(`kbdb` worker 的 `/entries`),泛化端點掛在 **cypher-executor**(已是 recipe 公庫 + workflow CRUD 的所在,且已有 KBDB fetch 慣例)。**不新建 worker、不 service binding、不 wrangler**(arcrun-primer A 類)。 + +### 關鍵決策 + +| 決策 | 選擇 | 原因 | 放棄的選項 | +|------|------|------|----------| +| **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 embed,workflow-discovery 已證);recipe KV 公庫已上線穩定,重寫=在可用機制上重投資(mistakes 教訓) | ❌ 全部塞 KV(違鐵律、無語意搜尋);❌ 逼 recipe 立刻遷 KBDB(負 ROI,列未來選項) | +| **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 一起 pull;component 只偵測引導、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 端沒判斷依據) | + +### 統一公庫 record 模型(R1) + +公庫一筆 = KBDB entry,`entry_type='public_artifact'`,`owner_id=author`(歸屬即隔離),`metadata_json` 承載身份與市場鍵,`content` 放 canonical_id(供 keyword/semantic search)+ `metadata_json.embed=true` 開語意搜尋: + +```jsonc +// public_artifact entry.metadata_json +{ + "uuid": "…", // 唯一身份(誕生即領,沿用 §7.5.5) + "type": "workflow", // recipe | workflow | template + "canonical_id": "daily_digest", + "author": "leo", // 該 uuid 投稿者;'system'=種子 + "derived_from": "…uuid?", // 可選:fork 溯源 + "display_name": "每日摘要", + "description": "…", // 供語意搜尋,強制非空(沿用 workflow-discovery R1) + "embed": true, // 開 Vectorize + "portable_body": { … }, // 見「可攜格式」 + "dependency_manifest": [ … ] // 見「依賴解析」 + // market_stat 不存這裡——per-uuid 記在既有 recipe-stats 機制(KBDB),import 時 fetch +} +``` + +> **市場數據**:沿用 recipe `fetchMarketStat`(KBDB `/recipe-stats/:id`,per-uuid)。泛化為 `/artifact-stats/:uuid`(或直接復用 recipe-stats 表,key=uuid 本就型別無關)。**不在投稿時寫自報數**(沿用 §7.3:自報數只當存證 `*_submission` entry,不併真實計數,避免污染市場)。 + +### 可攜格式(export,R2 / US-3) + +每型 `portable_body` = 該型的自足定義,**去識別化 + 去機密**: + +- **recipe**:既有 RecipeDefinition 去掉 `uuid/author/created_at`(導入時重領),保留 endpoint/method/headers/body/auth_service/`credentials_required`(只有 key 名,無值)。 +- **workflow**:`{ name, flow, config, description }`(cypher 三元組 + 節點設定)。`config` 內對零件的引用(`component: rec_xxx` / `component: `)保留;credential 引用維持 `{{credential.xxx}}` 模板(無值)。 +- **template**:`{ name, slots[], description }`。 + +export 檔(YAML/JSON,二選一,預設 YAML 對齊 workflow.yaml 慣例)= `portable_body` + `dependency_manifest` + `type`/`canonical_id` 標頭。自足=任何相同 Arcrun 部署 import 後可跑(前提:component 已具備、credential 已填)。 + +### 泛化端點(R3,K1 讀側泛化) + +掛在 cypher-executor,`type` 為必帶 query/param。行為對照 recipe `/public-recipes*` 完全同構: + +- `GET /public-artifacts?type=&q=&limit=&offset=` — 搜/列公庫。同 canonical_id 回多筆(多作者),各附 `market_stat`。落空(q 無命中)→ `{ found:false, type, query, hint }` 創作引導(沿用 §7.5.6)。`type` 省略=跨型別搜(回傳項帶各自 type)。 +- `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/template,recipe 沿用既有 `/public-recipes`(見 tasks 分期)。 + +### 導入語意 + materialize adapter(R4) + +`pull(type, canonical_id)` = +1. `GET /public-artifacts/:type/:canonical_id` 取全文(含 market 最佳版本 + dependency_manifest)。 +2. **先解依賴**(見下),再落地。 +3. **materialize(型別化)**: + - `workflow` → `POST /webhooks/named`(既有 push;owner_id=自己 api_key/namespace)。 + - `template` → `POST /templates`(既有 create_template)。 + - `recipe` → `installRecipeRecord`(既有)。 +4. 回報:落地的 uuid + 依賴處理結果(已 pull 的 recipe/template、缺的 component、待填 credential)。 + +### 依賴解析(R5 / K4)—— 關鍵設計點 + +一個 workflow 常引用四類東西。import 時**分類處理,各走各的邊界**: + +| 依賴類 | 來源(怎麼認) | 導入處理 | 為何這樣 | +|---|---|---|---| +| **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 與零件案的**界線落點** | +| **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)。 +- **遞迴有界**:manifest 逐項 pull,維護 visited set 防環 + 深度上限(建議 5),超限回報中止並列未解項。 + +### 安全與審核(R7 / K5)—— 對照 Arcrun#23 教訓 + +- **#23 教訓**:`publish_component` 零人閘(提交即 active/public + MCP 全域)=攻擊面。結構解已定:**廢 MCP 發布路徑、零件投稿唯一入口=PR**(`arcrun-components`)。 +- **本 SDD 的分界**:資料 artifact(recipe/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 依賴同樣過這層。 + 3. **零件閘不鬆動**:workflow 帶再多引用,也**不能**讓一個未經 PR 的新零件進入 host。缺零件=停在引導,這道牆就是防「拿 workflow 當殼夾帶惡意零件」。 + 4. **credential 零傳輸**:機密不可攜,杜絕投稿夾帶他人 token / 誘導填入釣魚 credential(import 端自己 `acr creds push`)。 +- **投稿存證**:submit 寫一筆 `artifact_submission` entry(誰、何時、投了什麼 uuid、自報 stat)當**法律歸責軌跡**(沿用 recipe §7.3),不當門檻。 + +### API / 介面定義(R6 三層對齊) + +| 層 | recipe(既有樣板) | 本 SDD 新增(workflow/template,泛化) | +|---|---|---| +| HTTP | `/public-recipes*`、`/recipes/submit` | `/public-artifacts*`、`/public-artifacts/submit`(`type=` 打通三型) | +| MCP | `arcrun_recipe_search/pull/submit_p` | `arcrun_artifact_search/pull/submit_p`(帶 `type` 參數)+ `arcrun_workflow_export` / `arcrun_template_export` | +| CLI | `acr recipe search/pull/submit-p` | `acr workflow search/pull/submit-p/export`、`acr template search/pull/submit-p/export`(薄殼包泛化端點) | + +> MCP/CLI 面向使用者可保留型別化命名(`acr workflow pull` 比 `acr artifact pull --type=workflow` 更順口、更 low-code),**底層打同一泛化端點**。=「對外型別化措辭、對內泛化實作」,兼得可讀性與 DRY。 + +### 資料模型 + +- 公庫 record:KBDB `public_artifact` entry(見上)。**不建新表**(entry_type + metadata_json 承載,KBDB 鐵律)。 +- market_stat:復用既有 KBDB recipe-stats(key=uuid,型別無關)。 +- 存證:`artifact_submission` entry。 +- 私庫落地:沿用各型既有儲存(workflow=WEBHOOKS KV+KBDB 雙寫、template=KBDB /templates、recipe=RECIPES KV),**不改**。 + +--- + +## 技術限制 + +- **不能**:新建 Worker、寫 Worker 程式碼、service binding、跑 wrangler、建 D1 新表、SQL 直寫(arcrun-primer 紅線;端點加在既有 cypher-executor / kbdb worker)。 +- **必須相容**:recipe 既有 `/public-recipes*` 路徑(不破現有 pull/submit);workflow 既有 `/webhooks/named` push 與 workflow-discovery 雙寫;template 既有 `/templates`。 +- **必須遵守**:儲存鐵律(長效→KBDB、機密→Secrets)、API-as-Wall(D6)、UUID 身份模型(§7.5.5)。 +- **效能**:公庫搜尋走 KBDB 語意/keyword(Vectorize 已在 workflow entry 證可行),避免 recipe KV `list({prefix})` 全掃在量大時疊加(kbdb-base §風險 已標)——這也是 workflow/template 公庫選 KBDB 而非 KV 的附帶好處。 + +--- + +## 驗收標準 + +完成的定義(CC 完成任何 task 前必須確認): +- [ ] `POST /public-artifacts/submit`(type=workflow)投稿後,`GET /public-artifacts?type=workflow&q=` 搜得到、帶 market_stat。 +- [ ] `GET /public-artifacts/workflow/:canonical_id` 回市場最佳作者版本;落空回 `{found:false,hint}`。 +- [ ] `acr workflow pull ` 把 workflow push 進自己 namespace,且遞迴 pull 其 recipe/template 依賴、列出缺的 component 與待填 credential。 +- [ ] `acr workflow export ` 產出自足 YAML,含 dependency_manifest,grep 不到任何機密值。 +- [ ] template 同上一套(submit-p/search/pull/export)跑通。 +- [ ] 投稿寫 `artifact_submission` 存證 entry;自報 stat 不進真實計數。 +- [ ] 一個引用「未具備零件」的 workflow,pull 時停在引導(不落地、不抓程式)。 + +--- + +## 相關文件 + +- `arcrun/kbdb-base/design.md` §7.5(recipe app-store / 公私庫雙向 / UUID 身份)— 本 SDD 的母範本。 +- `component-gatekeeping/`+`arcrun-components` repo — 零件走 PR 的界線另一側。 +- `workflow-discovery/` — workflow 已雙寫 KBDB + 語意搜尋,本 SDD 的公庫搜尋基礎。 +- `data-exfil-warning/` — import 時外呼信任檢查層。 +- `4-guides/arcrun-primer.md`(InkStoneCo 頂層)— A/B 兩類工作、紅線。 +- Arcrun#23(publish_component 零人閘教訓)、Arcrun#13(workflow-store / 移除 consent 閘)。 + +--- + +## 待 leo / richblack 拍板的設計點 + +1. **K2**:recipe 公庫是否收斂到 KBDB(與 workflow/template 同後端),或永久維持 KV 雙後端?本 SDD 預設「不動 recipe、泛化端點 front 兩後端」,收斂列未來選項。 +2. **export 預設格式**:YAML(對齊 workflow.yaml)vs JSON。本 SDD 預設 YAML、兩者皆支援。 +3. **MCP/CLI 命名**:型別化措辭(`acr workflow pull`)vs 泛化措辭(`acr artifact pull --type=`)。本 SDD 建議型別化對外、泛化對內。 +4. **依賴遞迴深度上限**:建議 5,是否合適。 +5. **K5 信任**:資料 artifact submit 全程無人閘是否可接受於**公開**公庫場景(vs 現況多為 self-hosted 私庫 pull);若未來上真公開公庫,是否要加 import 端的「首次 pull 陌生作者 → AI 摘要依賴清單給人看一眼」的軟提示(非硬閘)。 diff --git a/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md b/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md new file mode 100644 index 0000000..3c46f46 --- /dev/null +++ b/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md @@ -0,0 +1,96 @@ +# Artifact Sharing — Requirements + +> 狀態:草稿(待 review) +> 建立:2026-07-07 | 最後更新:2026-07-07 +> 負責人:Arcrun subagent(受 InkStoneCo 總管指派) +> 上游:對齊 `arcrun/kbdb-base` §7.5(recipe app-store / 公私庫雙向機制)、`component-gatekeeping`(零件走 PR)、`workflow-discovery`(workflow 已雙寫 KBDB)、`data-exfil-warning`(外呼風險層)。 + +--- + +## 一句話說明 + +把 recipe 已有的「公庫發布 / 下載導入 / 市場數據」app-store 模型,**擴展到 workflow 與 template(+slots)**,讓「資料庫就能完成的開發物」都能分享、發布、下載、導入、匯出。 + +--- + +## 背景與問題 + +Arcrun 的可攜開發物有三類存在 KBDB / KV 的**宣告式 record**: + +| Artifact | 現狀儲存 | 現有分享機制 | +|---|---|---| +| **recipe** | `RECIPES` KV(UUID 身份模型) | ✅ 完整:`GET /public-recipes`(搜/列)、`GET /public-recipes/:canonical_id`(pull 全文)、`POST /recipes/submit`(submit-p 投稿)、MCP `arcrun_recipe_search/pull/push/submit_p`、CLI `acr recipe search/pull/submit-p` | +| **workflow** | `WEBHOOKS` KV + KBDB `entry_type=workflow`(雙寫,供語意搜尋;workflow-discovery) | ❌ 只有本租戶 CRUD(`arcrun_push_workflow/list_workflows/get_workflow`)+本租戶語意搜尋(`/workflows/search`)。**無公庫 / submit / pull / export** | +| **template(+slots)** | KBDB `/templates`(name + slots) | ❌ 只有 `kbdb_create_template` / `kbdb_list_templates`。**無任何分享機制** | + +問題:**recipe 能被社群分享成長,workflow 與 template 卻鎖死在單一租戶**。使用者做好一個 workflow / template,沒有「發布給別人、或找別人的拉來用」的路。這違背 Arcrun「AI-Friendly 的 n8n」定位——n8n 有 workflow 範本市集,Arcrun 目前只有 recipe 有。 + +### 範圍界線(leo 拍板,最重要) + +- **本 SDD 只處理「資料庫就能完成的開發物」= recipe / workflow / template(+slots)**。它們是 KBDB / KV 裡的**可攜 record**,分享=發布到公庫 + 下載/導入進自己 namespace + 匯出成可攜格式。 +- **零件(component / code)不在此範圍**。零件是**程式**,走 **PR → 併入 main → 由部署/更新流程安裝**(`component-gatekeeping` + `arcrun-components` repo 已定案:投稿唯一入口=PR,廢 MCP publish 路徑,見 Arcrun#23 教訓)。本 SDD 只在「依賴解析」處與零件交界,不改零件安裝路徑。 + +--- + +## 用戶故事 + +> 貫穿的 low-code 原則:**「丟一個網址 / 一句話給 AI 即可裝」**(對齊 D6 補2「URL 由 AI 自動填、用戶零填寫」、arcrun-primer「AI 用 MCP/CLI/HTTP 就能建立、不碰底層」)。 + +### 發布側(我做好了,想分享) + +- **US-1(發布 workflow)**:我做好一個 `daily_digest` workflow,想讓別人也能用。我對 AI 說「把這個 workflow 發布到公庫」→ AI 呼叫 submit → 它成為公庫的一個具名作者版本,別人搜得到。 +- **US-2(發布 template)**:我設計了一個好用的 `crm_contact` template(slots: name/email/company/stage),想分享。對 AI 說「發布這個 template」→ 進公庫。 +- **US-3(匯出可攜檔)**:我要把一個 workflow 給不在同一部署的朋友(離線 / 走 email)。對 AI 說「匯出成檔案」→ 得到一份自足的 YAML/JSON(含依賴清單、不含機密)。 + +### 下載側(我想找別人的來用) + +- **US-4(搜公庫)**:我想找「發 Slack 通知」的現成 workflow。對 AI 說一句話 → AI 搜公庫,回幾個候選+各自市場數據(用過幾次、成功率),我挑一個。 +- **US-5(pull 導入)**:我看中一個 workflow,說「拉這個來用」→ AI 把它寫進**我自己的 namespace**(workflow→push、template→create_template),連同它引用的 recipe / template 依賴一起備妥,立即可用。 +- **US-6(丟網址即裝)**:朋友給我一個公庫連結 / canonical_id,我丟給 AI,AI 一條龍 pull + 解依賴 + 報告還缺哪些 credential 要我填。 + +### 作者 / 市場 + +- **US-7(多作者並存)**:公庫同一個 `daily_digest` 可以有 Leo 版、John 版,各自 uuid、各自累積市場數據,pull 時預設給市場最佳版本(沿用 recipe §7.5.5)。 +- **US-8(落空即創作)**:我搜的東西公庫沒有,AI 不該只回空結果,而是引導「你可以自己做一個成為第一個作者」(沿用 recipe §7.5.6)。 + +--- + +## 功能需求 + +- **R1 公庫 record 模型統一**:三型 artifact 在公庫共用一致的身份/歸屬/市場欄位——`uuid`(唯一身份)、`type`(recipe/workflow/template)、`canonical_id`、`author`、`derived_from`、`market_stat`(per-uuid success/failure)。沿用 recipe UUID 身份模型(kbdb-base §7.5.5)。 +- **R2 可攜格式(export)**:每型能匯出成自足的 YAML/JSON,含 `dependency_manifest`(引用的 component/recipe/template/credential 清單),**絕不含機密值**。 +- **R3 公庫端點**:搜/列(帶市場數據,落空回創作引導)、取全文(pull 用,多作者選最佳)、投稿(submit-p,新增作者版本不覆蓋)。三型都要。 +- **R4 導入語意(pull)**:pull = 把公庫定義寫進自己 namespace——workflow→`push`(/webhooks/named)、template→`create_template`、recipe→既有 `installRecipeRecord`。 +- **R5 依賴解析**:導入一個 workflow 時,遞迴處理它引用的 recipe/template(一起 pull)、驗證引用的 component 是否已具備(缺→引導走 PR/部署,**不自動抓程式**)、列出需要的 credential(引導 `acr creds push`,**不隨 artifact 傳輸**)。 +- **R6 三介面對齊**:HTTP 端點 → MCP tool → CLI 三層都補齊(沿用 recipe 三層樣板)。 +- **R7 安全**:對照 Arcrun#23(publish_component 零人閘教訓)明確界定——資料 artifact 走 app-store 市場信任(無 submit 前置人閘,leo 2026-06-29 已對 recipe 拍板移除 consent 閘);真正的程式攻擊面(零件)鎖在 PR 路徑。導入時以市場數據 + 依賴清單 + `data-exfil-warning` 外呼檢查作為信任判斷點。 + +--- + +## 非功能需求 / 對齊鐵律 + +- **儲存鐵律(arcrun-primer / 2026-07-06 leo 釘死)**:新增的公庫與可攜 record 都是**長效資料 → KBDB / D1**,禁止為閃避 KBDB 塞 KV;禁止建新表(用 template/slots / entry_type 承載)。機密 → CF Worker Secrets,永不進可攜檔。 +- **API-as-Wall(D6)**:全走 KBDB API(MCP/CLI/HTTP),插件層禁 SQL 直寫 D1。 +- **不碰 wrangler / 不自建 Worker**:這是 A 類應用邏輯(arcrun-primer 兩類工作表),端點加在既有 cypher-executor / kbdb worker,不新建 standalone worker、不 service binding。 +- **回應語言**:面向使用者的提示訊息正體中文。 + +--- + +## Out of Scope(明確排除,避免 CC 自行延伸) + +- **零件(component/code)的分享/安裝**——走 PR,另案(`component-gatekeeping` / `arcrun-components`)。本 SDD 只在依賴解析處**偵測**零件缺口並引導,不安裝零件。 +- **credential 的分享**——機密永不可攜。只匯出「需要哪些 key」的清單。 +- **跨環境市場數據聚合層**(self-hosted 各部署的真實成功率匯總回公庫)——沿用 kbdb-base §7.3/§7.5 5.5「另排」,本 SDD 只讀既有 per-uuid market_stat,不做聚合管道。 +- **recipe 既有公庫路徑的重寫 / 從 KV 遷 KBDB**——recipe 現行 KV 路徑已上線且穩定,不在此動它(避免「在既有可用機制上重投資」)。本 SDD 為 workflow/template 建 KBDB-native 公庫,recipe 是否收斂為未來選項(見 design 關鍵決策)。 +- **SaaS / api-key 發放**——沒有 SaaS(D21)。self-hosted 唯一形態,公庫連線走既有部署 URL。 + +--- + +## 驗收標準(US 對應) + +- [ ] US-1/US-2:`acr workflow submit-p ` / `acr template submit-p ` 能把私庫 artifact 投進公庫,成為具名作者版本(回 uuid)。 +- [ ] US-3:`acr workflow export ` 產出自足 YAML,含 dependency_manifest、零機密值。 +- [ ] US-4:`acr workflow search ` 回候選 + 各自 market_stat;落空回創作引導。 +- [ ] US-5/US-6:`acr workflow pull ` 把定義寫進自己 namespace,且遞迴 pull recipe/template 依賴、報告缺的 component 與待填 credential。 +- [ ] US-7:公庫同 canonical_id 多作者版本並存,pull 預設回 market_stat 最佳版本。 +- [ ] US-8:搜尋/取用落空回 `{ found:false, hint }` 創作引導,非空陣列。 diff --git a/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md b/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md new file mode 100644 index 0000000..d480f28 --- /dev/null +++ b/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md @@ -0,0 +1,124 @@ +# Artifact Sharing — Tasks + +> 權威來源:此檔案是進度真相,不是 CLAUDE.md 或對話。 +> 規則:動手前標 [🔄],完成立刻標 [x],不批次更新。 +> 依賴:design.md 的關鍵決策 K1-K5;母範本=`cypher-executor/src/routes/recipes.ts`(recipe 公庫)。 + +--- + +## Phase 1:統一公庫模型 + 泛化端點(後端地基) + +### 前置條件 +- [ ] design.md K1(泛化讀/型別化寫)、K2(KBDB 後端)已 review 無反對。 +- [ ] 確認 KBDB `/entries` + `/entries/search` 現況(workflow-discovery 已用,沿用即可)。 + +### Tasks + +- [ ] 1.1 定義 `public_artifact` entry 形狀 + `portable_body` / `dependency_manifest` 型別(三型共用) + - 驗收:TS interface 落在 cypher-executor(或 shared types),涵蓋 recipe/workflow/template 三型 portable_body 的 union。 + - 注意:不建新表——entry_type + metadata_json 承載(KBDB 鐵律 D6)。 + +- [ ] 1.2 `GET /public-artifacts?type=&q=&limit=&offset=`(搜/列,帶 market_stat,落空回創作引導) + - 驗收:type=workflow 投一筆後搜得到、附 market_stat;q 無命中回 `{found:false,type,query,hint}`。 + - 注意:邏輯照抄 recipe `/public-recipes`,差別=走 KBDB `/entries/search`(entry_type=public_artifact + type filter)而非 KV list。 + +- [ ] 1.3 `GET /public-artifacts/:type/:canonical_id?author=`(取全文,多作者選市場最佳) + - 驗收:多作者版本並存時回 success_count 最高版;落空回創作引導。 + - 注意:選版邏輯沿用 recipe `fetchMarketStat` per-uuid(泛化為 `/artifact-stats/:uuid` 或復用 recipe-stats)。 + +- [ ] 1.4 `POST /public-artifacts/submit`(submit-p,新增作者版本 + 存證) + - 驗收:投稿領新 uuid、不覆蓋同 canonical;寫一筆 `artifact_submission` entry;自報 stat 不進真實計數。 + - 注意:沿用 recipe submit 的「新 uuid=新作者版本」與 fire-and-forget 存證。 + +- [ ] 1.5 recipe 相容轉接:泛化端點對 `type=recipe` 轉呼既有 KV 公庫路徑 + - 驗收:`GET /public-artifacts?type=recipe` 結果與既有 `/public-recipes` 一致(不破現況)。 + - 注意:K2——對外一套 API、對內兩後端;**不改** recipe 既有 `/public-recipes*` 與 KV 儲存。可延後(先只上 workflow/template,見 §狀態)。 + +--- + +## Phase 2:可攜格式 export + 依賴清單 + +> 前置條件:Phase 1 的 portable_body 型別(1.1)定案。 + +- [ ] 2.1 三型 export:從私庫定義產出自足 `portable_body`(去 uuid/author/時間戳、去機密) + - 驗收:workflow/template/recipe 各能 export 成 YAML;grep 不到任何機密值、不含 credential value。 + - 注意:workflow 保留 `{{credential.xxx}}` 模板(無值);recipe `credentials_required` 只留 key 名。 + +- [ ] 2.2 dependency_manifest 產生器:掃 portable_body 抽引用(component/recipe/template/credential) + - 驗收:一個引用 http_request+recipe+寫 template+用 credential 的 workflow,manifest 正確列出四類依賴。 + - 注意:manifest 在 export/submit 時算好存進 record(import 端免反解)。這是 import 信任預覽面(K5)。 + +- [ ] 2.3 export 落檔(YAML 預設,JSON 可選)= portable_body + manifest + type/canonical 標頭 + - 驗收:export 檔在另一相同部署 import 後可跑(前提零件已具備、credential 已填)。 + +--- + +## Phase 3:導入語意 pull + materialize adapter + 依賴解析 + +> 前置條件:Phase 1(端點)+ Phase 2(manifest)完成。 + +- [ ] 3.1 materialize adapter(型別化落地):workflow→push、template→create_template、recipe→installRecipeRecord + - 驗收:pull 一個無依賴 workflow → 出現在自己 `arcrun_list_workflows`;template 同理進 `kbdb_list_templates`。 + - 注意:owner_id=自己 namespace(租戶隔離,沿用既有身份模型)。 + +- [ ] 3.2 依賴解析引擎(有界遞迴):讀 manifest 分類處理 + - 驗收:pull 一個引用 recipe R + template T 的 workflow → R/T 自動 co-pull 進私庫;visited set 防環 + 深度上限 5。 + - 注意:K4——recipe/template co-pull;component 只偵測(對照 `acr parts`)缺則引導 PR、**不抓程式**;credential 只彙總 key 名引導 `acr creds push`。 + +- [ ] 3.3 component 缺口偵測 + 引導(界線落點) + - 驗收:pull 一個引用「本部署沒有的零件」的 workflow → 停在引導(不落地、不抓程式),訊息指向 PR/`arcrun-components`。 + - 注意:這道牆=防「workflow 當殼夾帶惡意零件」(#23)。缺零件必須是硬停,不是警告後照裝。 + +- [ ] 3.4 credential 清單引導 + - 驗收:pull 後回報彙總的待填 key 清單 + `acr creds push` 指引;artifact 內無任何機密值。 + +--- + +## Phase 4:MCP + CLI 三層對齊 + +> 前置條件:Phase 1-3 端點與語意就緒。 + +- [ ] 4.1 MCP tools:`arcrun_artifact_search/pull/submit_p`(帶 type)+ `arcrun_workflow_export`/`arcrun_template_export` + - 驗收:MCP tools/list 出現新 tool;search→pull→export 端到端跑通(對照既有 `arcrun_recipe_*` 樣板)。 + - 注意:tool 名走 `brand.ts` toolName() 單一來源(沿用現有慣例)。 + +- [ ] 4.2 CLI:`acr workflow search/pull/submit-p/export`、`acr template search/pull/submit-p/export` + - 驗收:對照 `cli/src/commands/recipe.ts` 樣板;型別化措辭對外、底層打泛化 `/public-artifacts` 端點。 + - 注意:落空回創作引導文案(沿用 recipe search 落空體驗)。 + +- [ ] 4.3 文件:GUIDE/README/llms.txt 補三型分享的用法(低碼「丟網址/一句話即裝」示例) + - 驗收:文件零殘留舊工具名;含 US-6「丟網址即裝」示例。 + +--- + +## Phase 5(可選 / 未來):安全信任面 + recipe 收斂 + +- [ ] 5.1 import 端 `data-exfil-warning` 外呼檢查接線(pull 的 recipe 依賴過同層警示) + - 驗收:pull 一個 endpoint 域名異常的 recipe → import 端出警示(非硬擋)。 +- [ ] 5.2(待 leo 拍板 K2)recipe 公庫是否從 KV 收斂到 KBDB `public_artifact` + - 注意:非阻塞,列未來選項;現況「不動 recipe」已能運作。 +- [ ] 5.3(待 leo 拍板 K5)公開公庫場景的 import 軟提示(首次 pull 陌生作者→AI 摘要依賴給人看) + +--- + +## 完成定義 + +整個 SDD 完成 = 以下全部達成: +- [ ] 所有 Phase 1-4 tasks 標 [x](Phase 5 為可選/未來) +- [ ] 驗收標準通過(design.md 驗收清單有客觀證據) +- [ ] design.md 與實作一致(如有出入需更新) +- [ ] 零件界線未被破壞:無任何路徑讓未經 PR 的零件因 artifact 分享進入 host + +--- + +## 狀態說明 + +| 標記 | 意義 | +|------|------| +| `[ ]` | 未開始 | +| `[🔄]` | 進行中(當前 session)| +| `[x]` | 完成(有驗收證據)| +| `[~]` | 暫緩(說明原因)| +| `[!]` | 阻擋中(說明阻擋原因)| + +> **建議施作順序**:先 workflow 全鏈(Phase 1-4 只做 workflow)跑通一個型別的閉環,再複製到 template;recipe 相容轉接(1.5)與收斂(5.2)最後或不做。理由=先證泛化模型對一個型別成立,再擴,避免三型並行時模型未穩就 3× 返工。 -- 2.52.0 From 1d7f69215ab066e58955a4fad59a4d05a3356bd7 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 7 Jul 2026 09:09:37 +0000 Subject: [PATCH 2/2] =?UTF-8?q?docs(spec):=20artifact-sharing=20=E5=AF=A9?= =?UTF-8?q?=E6=9F=A5=E5=B0=8D=E9=BD=8A=20=C3=972=20=E2=80=94=20K2=20?= =?UTF-8?q?=E6=94=B9=20KBDB=20=E5=94=AF=E4=B8=80=E5=85=AC=E5=BA=AB?= =?UTF-8?q?=E5=BE=8C=E7=AB=AF=EF=BC=88=E5=B0=8D=E9=BD=8A=20#16=EF=BC=89+?= =?UTF-8?q?=20=E9=9B=B6=E4=BB=B6=E7=95=8C=E7=B7=9A=E7=85=A7=20#23/D29?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 審查意見兩處(總管 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 Claude-Session: https://claude.ai/code/session_015d5jDbuqT5Htwv3Q88XXKk --- .../3-specs/arcrun/artifact-sharing/design.md | 20 +++++++++---------- .../arcrun/artifact-sharing/requirements.md | 8 ++++---- .../3-specs/arcrun/artifact-sharing/tasks.md | 12 +++++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md b/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md index e06ca29..775f379 100644 --- a/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md +++ b/system-dev/docs/3-specs/arcrun/artifact-sharing/design.md @@ -30,7 +30,7 @@ - 安全與審核設計(app-store 市場信任 vs 零件 PR 閘的分界)。 ### 不包含(Out of Scope) -- 零件安裝(PR 路徑,另案);credential 分享;跨環境市場聚合層;recipe 從 KV 遷 KBDB;SaaS/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 embed,workflow-discovery 已證);recipe KV 公庫已上線穩定,重寫=在可用機制上重投資(mistakes 教訓) | ❌ 全部塞 KV(違鐵律、無語意搜尋);❌ 逼 recipe 立刻遷 KBDB(負 ROI,列未來選項) | +| **K2 公庫儲存後端** | **KBDB 是唯一公庫後端**(`entry_type=public_artifact`)。workflow/template 一開始就建在 KBDB;recipe 公庫隨 **#16(RECIPES KV→KBDB 遷移)**收斂進同一後端。過渡期(#16 落地前)泛化端點可暫時把 `type=recipe` 轉呼既有 KV 路徑,但 **KV 公庫=過渡態、非穩態**,#16 完成即拆轉接 | 對齊儲存鐵律(長效→KBDB)+白拿 KBDB 語意搜尋(Vectorize embed,workflow-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 一起 pull;component 只偵測引導、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/template,recipe 沿用既有 `/public-recipes`(見 tasks 分期)。 +> **recipe 相容(過渡)**:終態=三型都走 KBDB `public_artifact` 路徑(K2:KBDB 唯一公庫後端)。#16(RECIPES KV→KBDB)落地前的過渡期,泛化端點對 `type=recipe` 暫時轉呼既有 KV 公庫路徑(`listAllRecipes`/`installRecipeRecord`)——這段轉接碼是**過渡碼**,#16 完成後 `type=recipe` 改走 KBDB、轉接即拆,不留雙後端。可先只上 workflow/template,recipe 沿用既有 `/public-recipes`(見 tasks 分期)。 ### 導入語意 + materialize adapter(R4) @@ -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 的分界**:資料 artifact(recipe/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 慣例) ### 資料模型 -- 公庫 record:KBDB `public_artifact` entry(見上)。**不建新表**(entry_type + metadata_json 承載,KBDB 鐵律)。 +- 公庫 record:KBDB `public_artifact` entry(見上),**KBDB 是唯一公庫後端**(K2;recipe 過渡期例外見上)。**不建新表**(entry_type + metadata_json 承載,KBDB 鐵律)。 - market_stat:復用既有 KBDB recipe-stats(key=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.5(recipe 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.yaml)vs JSON。本 SDD 預設 YAML、兩者皆支援。 3. **MCP/CLI 命名**:型別化措辭(`acr workflow pull`)vs 泛化措辭(`acr artifact pull --type=`)。本 SDD 建議型別化對外、泛化對內。 4. **依賴遞迴深度上限**:建議 5,是否合適。 diff --git a/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md b/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md index 3c46f46..67b8847 100644 --- a/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md +++ b/system-dev/docs/3-specs/arcrun/artifact-sharing/requirements.md @@ -28,7 +28,7 @@ Arcrun 的可攜開發物有三類存在 KBDB / KV 的**宣告式 record**: ### 範圍界線(leo 拍板,最重要) - **本 SDD 只處理「資料庫就能完成的開發物」= recipe / workflow / template(+slots)**。它們是 KBDB / KV 裡的**可攜 record**,分享=發布到公庫 + 下載/導入進自己 namespace + 匯出成可攜格式。 -- **零件(component / code)不在此範圍**。零件是**程式**,走 **PR → 併入 main → 由部署/更新流程安裝**(`component-gatekeeping` + `arcrun-components` repo 已定案:投稿唯一入口=PR,廢 MCP publish 路徑,見 Arcrun#23 教訓)。本 SDD 只在「依賴解析」處與零件交界,不改零件安裝路徑。 +- **零件(component / code)不在此範圍**。零件是**程式**,貢獻已**整層搬到獨立 repo `Leo/arcrun-components`**:唯一入口=**fork→PR→人審**→併 main→由部署/更新流程安裝(#23/D29 定案;`arcrun_publish_component` 路徑廢除)。本 SDD 的市場只在「依賴解析」處與零件交界:**偵測缺件→引導去該 repo 開 PR,永不傳輸/安裝零件程式**。 --- @@ -61,7 +61,7 @@ Arcrun 的可攜開發物有三類存在 KBDB / KV 的**宣告式 record**: - **R2 可攜格式(export)**:每型能匯出成自足的 YAML/JSON,含 `dependency_manifest`(引用的 component/recipe/template/credential 清單),**絕不含機密值**。 - **R3 公庫端點**:搜/列(帶市場數據,落空回創作引導)、取全文(pull 用,多作者選最佳)、投稿(submit-p,新增作者版本不覆蓋)。三型都要。 - **R4 導入語意(pull)**:pull = 把公庫定義寫進自己 namespace——workflow→`push`(/webhooks/named)、template→`create_template`、recipe→既有 `installRecipeRecord`。 -- **R5 依賴解析**:導入一個 workflow 時,遞迴處理它引用的 recipe/template(一起 pull)、驗證引用的 component 是否已具備(缺→引導走 PR/部署,**不自動抓程式**)、列出需要的 credential(引導 `acr creds push`,**不隨 artifact 傳輸**)。 +- **R5 依賴解析**:導入一個 workflow 時,遞迴處理它引用的 recipe/template(一起 pull)、驗證引用的 component 是否已具備(缺→引導去 `Leo/arcrun-components` 開 PR(fork→PR→人審),**永不傳輸/安裝零件程式**)、列出需要的 credential(引導 `acr creds push`,**不隨 artifact 傳輸**)。 - **R6 三介面對齊**:HTTP 端點 → MCP tool → CLI 三層都補齊(沿用 recipe 三層樣板)。 - **R7 安全**:對照 Arcrun#23(publish_component 零人閘教訓)明確界定——資料 artifact 走 app-store 市場信任(無 submit 前置人閘,leo 2026-06-29 已對 recipe 拍板移除 consent 閘);真正的程式攻擊面(零件)鎖在 PR 路徑。導入時以市場數據 + 依賴清單 + `data-exfil-warning` 外呼檢查作為信任判斷點。 @@ -78,10 +78,10 @@ Arcrun 的可攜開發物有三類存在 KBDB / KV 的**宣告式 record**: ## Out of Scope(明確排除,避免 CC 自行延伸) -- **零件(component/code)的分享/安裝**——走 PR,另案(`component-gatekeeping` / `arcrun-components`)。本 SDD 只在依賴解析處**偵測**零件缺口並引導,不安裝零件。 +- **零件(component/code)的分享/安裝**——唯一路徑=獨立 repo `Leo/arcrun-components` 的 fork→PR→人審(#23/D29 定案),另案。本 SDD 只在依賴解析處**偵測**零件缺口並引導去該 repo 開 PR,**永不傳輸/安裝零件程式**。 - **credential 的分享**——機密永不可攜。只匯出「需要哪些 key」的清單。 - **跨環境市場數據聚合層**(self-hosted 各部署的真實成功率匯總回公庫)——沿用 kbdb-base §7.3/§7.5 5.5「另排」,本 SDD 只讀既有 per-uuid market_stat,不做聚合管道。 -- **recipe 既有公庫路徑的重寫 / 從 KV 遷 KBDB**——recipe 現行 KV 路徑已上線且穩定,不在此動它(避免「在既有可用機制上重投資」)。本 SDD 為 workflow/template 建 KBDB-native 公庫,recipe 是否收斂為未來選項(見 design 關鍵決策)。 +- **recipe RECIPES KV→KBDB 遷移的執行**——由 **#16** 負責(另案進行中),本 SDD 不動手遷、也不重寫 recipe 既有 `/public-recipes*`。但設計前提=**KBDB 是唯一公庫後端**(design K2):#16 落地前泛化端點對 `type=recipe` 的 KV 轉接只是過渡碼,#16 完成即拆,**KV 公庫不是穩態**。 - **SaaS / api-key 發放**——沒有 SaaS(D21)。self-hosted 唯一形態,公庫連線走既有部署 URL。 --- diff --git a/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md b/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md index d480f28..1d5e627 100644 --- a/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md +++ b/system-dev/docs/3-specs/arcrun/artifact-sharing/tasks.md @@ -30,9 +30,9 @@ - 驗收:投稿領新 uuid、不覆蓋同 canonical;寫一筆 `artifact_submission` entry;自報 stat 不進真實計數。 - 注意:沿用 recipe submit 的「新 uuid=新作者版本」與 fire-and-forget 存證。 -- [ ] 1.5 recipe 相容轉接:泛化端點對 `type=recipe` 轉呼既有 KV 公庫路徑 +- [ ] 1.5 recipe 相容轉接(**過渡碼**,#16 落地前):泛化端點對 `type=recipe` 暫時轉呼既有 KV 公庫路徑 - 驗收:`GET /public-artifacts?type=recipe` 結果與既有 `/public-recipes` 一致(不破現況)。 - - 注意:K2——對外一套 API、對內兩後端;**不改** recipe 既有 `/public-recipes*` 與 KV 儲存。可延後(先只上 workflow/template,見 §狀態)。 + - 注意:K2——**KBDB 是唯一公庫後端**,KV 轉接非穩態:#16(RECIPES KV→KBDB)完成後 `type=recipe` 改走 KBDB、本轉接即拆(見 5.2)。**不改** recipe 既有 `/public-recipes*` 與 KV 儲存(遷移本體=#16 的事)。可延後(先只上 workflow/template,見 §狀態)。 --- @@ -66,8 +66,8 @@ - 注意:K4——recipe/template co-pull;component 只偵測(對照 `acr parts`)缺則引導 PR、**不抓程式**;credential 只彙總 key 名引導 `acr creds push`。 - [ ] 3.3 component 缺口偵測 + 引導(界線落點) - - 驗收:pull 一個引用「本部署沒有的零件」的 workflow → 停在引導(不落地、不抓程式),訊息指向 PR/`arcrun-components`。 - - 注意:這道牆=防「workflow 當殼夾帶惡意零件」(#23)。缺零件必須是硬停,不是警告後照裝。 + - 驗收:pull 一個引用「本部署沒有的零件」的 workflow → 停在引導(不落地、**永不傳輸/安裝零件程式**),訊息指向獨立 repo `Leo/arcrun-components` 開 PR(fork→PR→人審,#23/D29)。 + - 注意:這道牆=防「workflow 當殼夾帶惡意零件」(#23;`arcrun_publish_component` 已廢除,勿在引導文案提它)。缺零件必須是硬停,不是警告後照裝。 - [ ] 3.4 credential 清單引導 - 驗收:pull 後回報彙總的待填 key 清單 + `acr creds push` 指引;artifact 內無任何機密值。 @@ -95,8 +95,8 @@ - [ ] 5.1 import 端 `data-exfil-warning` 外呼檢查接線(pull 的 recipe 依賴過同層警示) - 驗收:pull 一個 endpoint 域名異常的 recipe → import 端出警示(非硬擋)。 -- [ ] 5.2(待 leo 拍板 K2)recipe 公庫是否從 KV 收斂到 KBDB `public_artifact` - - 注意:非阻塞,列未來選項;現況「不動 recipe」已能運作。 +- [ ] 5.2(已定案,跟 #16 進度走)recipe 公庫收斂到 KBDB `public_artifact` + 拆 1.5 的 KV 過渡轉接 + - 注意:K2 已定(KBDB 唯一公庫後端,審查 2026-07-07 對齊 #16);遷移本體由 #16 執行,本項=#16 落地後把 `type=recipe` 切到 KBDB 路徑並移除轉接碼。非阻塞(過渡期 1.5 已能運作)。 - [ ] 5.3(待 leo 拍板 K5)公開公庫場景的 import 軟提示(首次 pull 陌生作者→AI 摘要依賴給人看) --- -- 2.52.0