1b687fedb0
leo:「刪掉,技術者才會寫 component,在 Arcrun repo 寫一條如何 contribute 指向另一個 repo 就好。」 實測病灶:總管想寫「定期打 API 然後通知」的 workflow(Python 約 10 行), 問 foreach_control 怎麼用 → MCP 回傳 TinyGo 寫 WASM 零件教學(白名單/syscall/ contract schema)=完全另一件事,40 分鐘未完成。 三處修正: 1. search_components 搜不到時的話術——原本建議 publish_component(把「我找不到」 翻譯成「你去造一個」,方向完全相反)。改為導向正確順序:語意搜尋知識庫→ auth-recipe list/scaffold→acr parts(http_request 能打任意 API)→acr list, 並明說 registry 可能是空的(已知問題),搜不到≠沒有這能力。 2. registry.ts 停用 publish_component / get_component_guide 兩個註冊 (檔案保留,只是不對 AI 暴露)。 3. 新增 CONTRIBUTING-components.md:三層責任分工(平台通用能力/熱門預鋪 recipe/ 冷門誰用到誰開發)、什麼時候才真需要新零件、真要貢獻走 PR 的流程。 typecheck 通過。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
213 lines
18 KiB
Markdown
213 lines
18 KiB
Markdown
# Pending Changes(規格變更緩衝區)
|
||
|
||
> 規則來源:`SDD-LIFECYCLE.md` 第 3、4 條。
|
||
> 規格層變更(核心設計/方向改變)**只有這一條路**:CC 把 change proposal 寫進「待裁決」——
|
||
> 變更摘要與觸發原因+影響分析(現行 SDD 哪些任務作廢/修改/不受影響/尚未完成)——然後**停止**,
|
||
> 等使用者明說「confirm」才依第 4 條開新 SDD;沒 confirm 就繼續依現行 SDD 工作。
|
||
> 多個 proposal 可並存,由人一次裁決。本檔不是 SDD,不掛 status。
|
||
|
||
## 待裁決
|
||
|
||
### P-2026-07-21:registry 寫入端+搜尋端修復(leo 親自交辦,最高優先)
|
||
|
||
> 提案人:總管交辦之 arcrun subagent。
|
||
> 觸發:leo 2026-07-21 —「一旦推進一個零件,就自動進 registry;recipe、workflow、app 都應該可以 registry,
|
||
> 不然搜不到。一邊是寫進去,另一邊是搜到,當然要有。」
|
||
> 判準:「Arcrun = 讓 AI 輕易建立程式碼」「AI 要覺得 Arcrun 比 Python 還簡單,絕不可迷路」。
|
||
> **依 D35:本任務找不到對應的 active SDD(現行 active=portal-auth,與本題無關),
|
||
> 故不動 code、不自建 SDD,寫本 proposal 後停止等 leo confirm。**
|
||
|
||
#### 一句話
|
||
|
||
registry 的寫入機制**存在且可用**,但它唯一的自動觸發點長在 GitHub Actions 上;
|
||
Actions 因防 flag 鐵律被整個刪除後(commit `037cf9b`),**寫入端失去觸發者、庫從此是空的**。
|
||
這不是「沒有機制」,是「機制的手被砍掉、沒補上替代觸發點」。
|
||
|
||
#### 根因(file:line 級)
|
||
|
||
| 事實 | 證據 |
|
||
|---|---|
|
||
| 寫入端點存在 | `registry/src/routes/components.ts:112` `POST /components/index-only`(metadata-only 索引,冪等) |
|
||
| 寫入實作存在 | `registry/src/actions/indexOnlyComponent.ts:44` 寫 `comp:{hash}:{ver}` + `idx:{canonical_id}` 兩個 KV key |
|
||
| 批次灌注腳本存在 | `registry/scripts/backfill-index.mjs`(掃 22 個 contract.yaml → POST index-only) |
|
||
| 單顆註冊腳本存在 | `registry/scripts/register-component.sh`(註解自稱「本地+CI 共用 SSOT」) |
|
||
| **唯一自動觸發點已不存在** | `git show 037cf9b^:.github/workflows/deploy.yml` 第 269-275 行有 `Register component in registry` step 呼叫上述 sh;`037cf9b` 刪除整個 `.github/workflows/`,**該 step 隨之消失,無替代品** |
|
||
| 從未跑過的實證 | 對 leo21c 跑 `REGISTRY_URL=... node scripts/backfill-index.mjs --dry-run` → 22 顆待灌;線上 `/components/search?q=http` 回 `count:0` |
|
||
|
||
→ **答案:是「有機制但從沒跑過」**(且失去觸發者),不是「沒有寫入機制」。
|
||
→ 附帶事實:`registry/wrangler.toml:26` 的 `[[routes]]` 寫死 `registry.arcrun.dev`,
|
||
self-hosted(leo21c)只能靠 workers.dev URL,backfill 腳本預設 `REGISTRY_URL` 也是官方域 —— 需帶環境變數才會打到自己的庫。
|
||
|
||
#### 重要更正:leo 要的東西**有一半已經存在,只是不在 registry 上**
|
||
|
||
`acr search <term>`(`cli/src/commands/search.ts`)已經是 leo 描述的「意圖驅動、跨類一次搜」——
|
||
它 fan-out 四個來源(component 靜態清單 / `/recipes` / `/auth-recipes` / `/webhooks/named`)。
|
||
**實測(2026-07-21,leo21c,真實輸出見交辦回報)**:
|
||
- `acr search http` → 命中零件 `http_request`(驗收劇本 1 ✅)
|
||
- `acr search notify` → 命中 recipe `line_notify_send` + auth-recipe `line_notify`(劇本 2 部分達成)
|
||
- `acr search github` → 命中 auth-recipe `github`(驗收劇本 3 ✅)
|
||
- `acr search telegram` → 命中 recipe `telegram_send` + auth-recipe `telegram`
|
||
|
||
→ **能力在 CLI 有、在 registry/MCP 沒有**。這正是薄殼原則(rule 07)被違反的典型:
|
||
同一個「跨類搜尋」能力長在介面層(CLI)而非 API,於是另一個薄殼(MCP)享受不到。
|
||
**修法的方向不是在 registry 重造一套搜尋,而是把 `acr search` 的 fan-out 能力下沉成 API 端點,CLI/MCP 同吃。**
|
||
|
||
#### 提案內容(四件,全部需 confirm 後才動)
|
||
|
||
**A. 寫入端:補回失去的觸發點(不復活 Actions)**
|
||
- A1. `acr push` / `acr deploy` 成功後自動呼叫 `POST /components/index-only`(本機發起、低頻、單 repo,守 D20 讀寫界線與防 flag 鐵律)。
|
||
- A2. `acr init` / `acr update` 部署完 22 顆零件後跑一次 backfill(讓新裝的人開箱即有索引)。
|
||
- A3. **recipe / workflow 不需要新的 registry 寫入路徑**——它們本來就活在 store(KV),
|
||
`acr recipe push` / `acr push` 當下就已「寫進去」。缺的只是**搜尋端讀得到**(見 B)。
|
||
→ leo 說的「recipe、workflow、app 都應該可以 registry」,正解是**統一搜尋面**,不是把它們搬進 registry KV 再存一份(那會製造第二份真相源)。
|
||
- A4. `app`(bundle)已有 P-2026-07-19 artifact-sharing 卷涵蓋,本卷不重複立案,只在搜尋面預留類別。
|
||
|
||
**B. 搜尋端:能力下沉 + 語意**
|
||
- B1. 在 **cypher-executor** 開 `GET /search?q=`(不是 registry——因為 recipe/workflow 的真相源在 cypher 的 KV),
|
||
server 端做 `acr search` 現有的四類 fan-out,回統一結果(含 `type` 欄位)。
|
||
- B2. `acr search` 與 MCP 新 tool `arcrun_search`(或改造 `arcrun_search_components`)雙雙改為呼叫 B1,介面層不再自行 fan-out(回歸薄殼)。
|
||
- B3. 語意搜尋:KBDB 那條路已驗證可用(Vectorize),把四類的 description 灌進去,讓「我要打一個 HTTP API」這種自然語言句命中 `http_request`。
|
||
現行 `registry/src/actions/queryComponents.ts:104` 明載「這是 Phase 0 的純文字比對版本,Phase 2 接入 Vectorize」——本項即補完該 Phase 2。
|
||
- B4. 搜不到時的文案改為「導向 recipe / 既有 workflow」,**移除「可以用 arcrun_publish_component 提交新零件」的建議**(見 C)。
|
||
|
||
**C. 斷掉「推人去寫零件」的路**
|
||
- C1. `mcp/src/tools/arcrun_search_components.ts:50` 搜不到時明文建議 `arcrun_publish_component` —— 違反 leo 既定規矩(零件走 PR、專業等級)。改為導向 recipe/workflow。
|
||
- C2. `arcrun_get_component_guide`(回 TinyGo 寫 WASM 教學)與 `arcrun_publish_component` 對一般使用者是誤導 → 建議降級為「專業模式」才暴露(預設不掛載),或在描述首句明寫「99% 情況你不需要這個,先用 recipe」。
|
||
- C3. **查證結果:零件相關「已拆到另一個 repo」未獲證實**——`registry/components/` 22 顆零件仍在本 repo,
|
||
wiki 與 git 均查無拆分紀錄。leo 的印象可能來自 `.github-public/` 對外鏡像(`GitHub mirror 發佈模型`)。**此點需 leo 確認**。
|
||
|
||
**D. 過時項**
|
||
- D1. MCP 仍要求已廢的 `api_key` 參數者共 **15 處**:`arcrun_introspection.ts`(4)、`arcrun_recipe.ts`(6)、`arcrun_workflow_crud.ts`(5)。
|
||
2026-07-20 已改 namespace 明碼 → 這些應改為由 server 端 namespace 推導,不再要 AI 傳。
|
||
- D2. **1042 的真正解法已確認並已落地**(本項無需修 code,只需更正記載):
|
||
`global_fetch_strictly_public` compatibility flag,已實裝於 `cypher-executor/wrangler.toml:13`
|
||
與 `.component-builds/http_request/wrangler.toml:8`。
|
||
leo 說的「開了一個什麼,把所有呼叫都視為外部」=**這個 flag**(讓 same-zone fetch 走公網前門)。
|
||
wiki 已有正確記載:`system-dev/wiki/cards/decisions/same-zone-1042用flag解不用binding.md`、
|
||
`mistakes.md:101`、`decisions-summary.md:84`。
|
||
→ 「graph_neighbors 改用 recipe 繞過」的過時說法**在本 repo wiki 查無此記載**(status.md:50-52 只寫 MCP tool PR),
|
||
該過時記載可能在頂層 InkStoneCo wiki 或 MEMORY.md,需由總管在該層更正。
|
||
|
||
#### 影響分析(D35 第 3 條要求)
|
||
|
||
- **現行 active SDD(portal-auth)**:完全不受影響,本提案不碰其任務。
|
||
- **`component-registry-canon`(status: paused,2026-05-07 建)**:**本題其實早有此卷**,
|
||
其 §1.2 診斷的根因與今日實測完全一致(「registry 活著但 index 空的,AI 找不到零件就會繞回 Python」),
|
||
尚有 **29 個未完成任務**。→ **建議:不新開 SDD,改為把此卷 resume 成 active**(並把 A/B/C/D 的新項增補進其 tasks),
|
||
這比另立新卷更符合 D35 第 4 條「先搬移未完成任務」的精神,也避免第二份重疊規格。
|
||
⚠️ 但這需要先把 portal-auth 收尾或轉 paused(單一活性鐵律),**此為 leo 的排序決策,不是 CC 能裁的**。
|
||
- **`workflow-discovery`(paused)/`library-map`(draft)**:與 B1 統一搜尋面高度重疊,resume 時應一併檢視是否合併。
|
||
|
||
#### 待 leo 拍板的四點
|
||
|
||
1. **排序**:要不要把 `portal-auth` 讓位、resume `component-registry-canon` 來做這件事?(單一活性鐵律強制二選一)
|
||
2. **C2**:`get_component_guide` / `publish_component` 要「預設不掛載」還是「留著但改描述」?(品味/方向)
|
||
3. **C3**:零件是否真的已拆到另一個 repo?(leo 記憶待證實)
|
||
4. **B3 語意搜尋**:四類描述灌進 Vectorize 會產生 embedding 呼叫成本,確認可行?(花錢)
|
||
|
||
## 已裁決
|
||
|
||
### P-2026-07-19:artifact-sharing 增補「App(bundle)+實例譜系+訂閱更新+多源分享」
|
||
|
||
> 狀態:**confirmed 2026-07-19**(leo「好的可走」)。四個拍板點總管採建議值(leo 可翻案):①排序=Phase 1.5 緊接 Phase 1、在 KV 退休(#16/#17)前後皆可並行 ②訂閱預設 policy=notify ③側載標記第一波=列表標記即可 ④P6 第一波=官方源+直連一個外源,org 私區留第二波。tasks 增補見 artifact-sharing/tasks.md「Phase 1.5」段。
|
||
|
||
> 提案人:雲端總管(leo 2026-07-19 對話三輪收斂後令「寫」)。
|
||
> 目標 SDD:`Leo/Arcrun` `system-dev/docs/3-specs/arcrun/artifact-sharing/`(#27+#31)。
|
||
> 依 D35:本檔為規格層 proposal,**寫入 pending-changes.md 後停下等 leo confirm**,confirm 前不動 tasks、不寫 code。
|
||
|
||
## 一句話
|
||
|
||
workflow/recipe/template 的實體在平台(CF/KBDB),不在 YAML——YAML 是隨叫隨到的視圖(搖桿)。
|
||
因此版本控制、譜系、更新通知必須是**平台內建能力**,git 降級為:引擎程式碼的家+人審 diff 面+災備快照。
|
||
本提案把 #27 公庫從「單品發布/拉取」補全成「App 商店+訂閱更新+實例譜系」。
|
||
|
||
## 背景(為什麼現在)
|
||
|
||
- 實證痛點:arcrun-rag(企業)與 Mira(個人)跑同族管線的兩份變體(rag_ingest v2 vs km_wiki_ingest),
|
||
「哪邊同步了沒」靠人腦;claude.ai 07-19 實測抓到的三個引擎缺口再證「修一次、兩實例都該自動受益」的通道不存在。
|
||
- T-pack-v2「repo 即真相源」是**過渡義肢**:因為平台缺版本層(KV 讀不回、無版本、無譜系),才用 git 代位。
|
||
義肢照 D15 前例:平台長出器官後拆。
|
||
- 地端版(workerd)將成第三個實例形態——在複雜度上升前把「App×實例×版本」模型立好。
|
||
|
||
## 提案內容(五件)
|
||
|
||
### P1. bundle 第四型(App)
|
||
- `public_artifact` 新增 `type=bundle`。portable_body=成員清單:
|
||
`[{type: workflow|recipe|template, canonical_id, uuid(鎖版) 或 version_policy(track-latest)}]`
|
||
+`install_params_schema`(安裝參數:多人開關、Gitea 端點、LLM provider…)+`conformance`(見 P5)。
|
||
- 「裝一個 App」=pull 一個 bundle,成員經既有 dependency_manifest 機制解析;
|
||
個人版與企業版=**同一個 bundle、不同 install params**。
|
||
- arcrun-rag 為第一個 bundle(現行 install.sh 即其手寫前身,落地時翻譯成 manifest)。
|
||
|
||
### P2. 訂閱與更新通知(可拒、可 pin)
|
||
- install/pull 時建立訂閱關係:新 entry `artifact_subscription`
|
||
(subscriber namespace、canonical_id、目前安裝 uuid、policy: notify|auto|pin)。
|
||
(`artifact_pull_event` 保持純事件帳本不改;訂閱是關係、事件是史料,分開存。)
|
||
- 新版 submit-p 後,訂閱者「得知」的通道**查詢式優先**:
|
||
`GET /subscriptions/updates`(實例/AI/console 隨時問「我有沒有落後」);
|
||
推播(notify workflow)為選配、且**禁止因發布事件自動 fan-out 到多實例**(D4 紅線——通知生成可以批次/排程,不掛事件觸發鏈)。
|
||
- 更新永遠是訂閱端的**顯式動作**:可更、可拒、可 pin 死版本。
|
||
|
||
### P3. installed_from 譜系+側載標記(隱形工作流可見化)
|
||
- 實例內每個 materialized artifact(workflow/recipe/template)落籍記
|
||
`{installed_from_uuid, installed_at, content_hash}`(entry metadata,不建表)。
|
||
- 平台即可回答四態:`up_to_date / behind / diverged(本地改過)/ sideloaded(無譜系,API 直建)`。
|
||
- list/console/MCP 的 workflow 列表帶狀態標記。**側載不禁止、只標記**(Android sideload 哲學);
|
||
「沒有 YAML 就不准」的 policy 不採納——對 AI 是降頻,可見性由本條提供。
|
||
- 既有 git 外掛式 drift 稽核(guard 對 hash)為過渡措施,本條落地後退役。
|
||
|
||
### P4. 更新與分岔語意
|
||
- update=拉新版重新 materialize(installed_from 換新 uuid)。
|
||
- `diverged` 者不自動覆蓋:提示二選一——fork(submit-p 推回公庫成自己的作者版本,derived_from 記溯源)或捨棄本地改動收新版。
|
||
- 對應 leo 模型:「Mira 和 Arcrun RAG 都 clone 了 rag app,都可以推回去存成新版本,收到更新通知但自己決定要不要更」。
|
||
|
||
### P5. conformance self-check 隨 bundle(驗收矩陣自動化)
|
||
- bundle 附驗收清單:介面×能力的機械檢查(例:portal 登入 200、MCP tools/list 含 kbdb_*+graph、
|
||
keyword/semantic/graph 三模式各一題 golden question 命中)。
|
||
- install/update 完自動跑、產報告;解「企業 GUI 驗了但企業 MCP/個人 GUI/個人 MCP 不知道、檢查到沒完沒了」——
|
||
可用性從人肉巡邏變安裝產物。地端(workerd)實例=同一張體檢單多跑一列。
|
||
|
||
### P6. registry=源(source)非地方:多源與點對點分享(leo 2026-07-19 追加)
|
||
- 公庫端點長在 cypher-executor=**每個實例都內建 registry 能力**;官方公開市場只是「預設源」。
|
||
- 實例可加多個源:公開市場/org 內部源/**另一個實例直連**(A 做了 App,B 把 A 加為源直接拉,CF-to-CF,不經公開市場——Homebrew tap 模式)。
|
||
- artifact 加 `visibility: public | org | unlisted`;外源拉取走既有 token 認證(portal-auth/MCP OAuth 機制,A 發「可拉取」token 給 B)。
|
||
- P3 落籍擴充:`installed_from` 記「源+uuid」;P2 訂閱跨源成立(B 訂閱「A 源上的 canonical_id」)。
|
||
- **信譽記分邊界**:私下/org 內分享的 pull 事件留在該源帳本,**不進公開信譽**;日後同 canonical 發布公開市場,溯源保留、私史不折算。
|
||
- 信任判斷仍在 import 端(#27 原則):來源是誰,列表標記說清楚。
|
||
|
||
### P6 鐵律:拉取=落地複本,runtime 零外部依賴(leo 2026-07-19 Drive 之問定形)
|
||
- pull/install=把 artifact(含 dependency_manifest 解析出的全部依賴,跨源亦然)**materialize 進本實例 KBDB**——複本式分發(npm/App Store),非引用式分享(Google Drive)。
|
||
- 源斷線/停止分享=只失去更新,**已裝的照跑**;狀態標 `source_lost`。互相參照在安裝時全落地,runtime 永不回頭找源;只有「查更新」動作碰源。
|
||
- 多源不亂的機制:裝完面對的是一張本地清單(每項帶源+五態標記);同 canonical_id 跨源衝突=安裝時顯式選源,不靜默合併;bundle 鎖版 uuid=lockfile 對應物。
|
||
|
||
### 排序定調:分享先行、投稿後行(leo 2026-07-19 收斂)
|
||
- **官方的本質=第一個策展人**(leo 定調):官方源不是特權角色,就是「把很多資源收集起來分享給大家的人」;公開市場=分享機制+官方獎勵制度(信譽層)疊上去,作為分享落地後的下一件事。
|
||
- **先做**:P6 最小版(官方源+直連外源)+P1+P3 → 這就是產品自己的部署通道(leo 官方源→客戶實例拉 arcrun-rag bundle;第一組 A/B=leo 與第一個客戶、以及 Mira);再 P2 訂閱更新。
|
||
- **後開**:公開投稿+信譽榜——空市場掛榜=鬼城,等 self-hosted 用戶密度夠再開(社群玩法)。
|
||
- **零代價保證**:#31「事件是真相、統計是視圖」——pull/submission 事件 day-one append,信譽晚開也能從頭算,先分享不欠投稿任何債。
|
||
|
||
### 附:獎勵/信譽(確認既有設計,非新增)
|
||
- 「貢獻 recipe 得 reputation」=#31 作者信譽經濟已設計(作者頁/聚合信譽/選版複合分/獎勵層預留、author 綁認證身份);事件 day-one append 保證信譽可事後計算。
|
||
- 本提案只補一句:**bundle(App)作者同樣累積信譽**——組裝 App 與寫 recipe 同屬貢獻。
|
||
|
||
## 影響分析
|
||
|
||
- **不建表**:全部走 entry_type+metadata_json(D6 鐵律);`artifact_subscription`/落籍 metadata 皆 template/slot 層。
|
||
- **與 Phase 1 關係**:不改既有 1.1–1.6 任務;本提案為 Phase 1.5(bundle/lineage/subscription 建在單品公庫之上)。
|
||
1.5 的 recipe KV 過渡(#16)不受影響。
|
||
- **與 D4 flag 鐵律**:通知採查詢式優先、禁事件 fan-out(見 P2),無 GitHub 流量、無 Actions。
|
||
- **與現行 installer**:過渡期 install.sh 續用;第一步可先讓 installer **代寫 installed_from 落籍**(義肢幫器官接生),
|
||
公庫端點好了再切換 pull 路徑——遷移平滑、無一次性大爆改。
|
||
- **受益者**:Mira 跟上企業版=「訂閱同一個 bundle 按更新」;未來 N 個客戶實例同此通道;地端版=第三個實例非第三套系統。
|
||
- **風險**:scope 擴張(#27 尚未動工就加型)——緩解:P1/P3 是最小核(bundle 形狀+落籍欄位),
|
||
P2 通知與 P5 self-check 可各自獨立分批落地;全部 compute-on-read 起步,物化快照沿用 #31 判準。
|
||
|
||
## 待 leo 拍板點
|
||
|
||
1. Phase 1.5 排序:在 Portal(#24/#25 已收官)之後、KV 退休(#16/#17)之前或之後?
|
||
2. 訂閱 policy 預設值:notify(通知不動手)?
|
||
3. 側載標記的呈現強度:只列表標記,或 console 加「無譜系 workflow」提醒區塊?
|
||
4. P6 多源第一波範圍:只做「官方源+直連一個外源」?org 私區(visibility=org)是否留第二波?
|
||
|
||
|