chore: D22 落地——docs/SDD/wiki/CLAUDE.md 進 repo(Gitea private 預設全 push)
頂層 D22 決策(leo 2026-07-03 拍板):推什麼由開發環境歸屬決定, Gitea private=除機敏值/build 產物/.github 外全 push。 解 T1.5 卡點:雲端工人 clone 拿得到 credential-store-migration.md,可就地改寫 SDD。 機敏掃描兩輪通過(新增 189 檔約 2.1MB,node_modules/dist/wasm 照舊排除)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,182 @@
|
||||
# workflow-discovery — Design
|
||||
|
||||
> **狀態**:草案,待確認。對應 `requirements.md`。
|
||||
> **建立**:2026-06-27(issue #8)
|
||||
|
||||
---
|
||||
|
||||
## 1. 設計總綱
|
||||
|
||||
三件事,全部把能力落在 API(cypher-executor + KBDB),CLI/MCP 只暴露:
|
||||
|
||||
1. **強制 description**:部署端點驗證 description 非空 → 否則 422/400 擋下(兩條路徑共用同一驗證)。
|
||||
2. **可搜的 metadata**:workflow metadata 同時寫進一個 **embeddable entry**(吃 issue #7 的 `/entries/search` 語意 + 降級)。
|
||||
3. **search_workflow 工具**:薄殼呼叫 cypher 的 workflow 搜尋端點,後者轉發 KBDB `/entries/search`,限本租戶。
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心決策 Q1:metadata 存哪(record vs entry vs 雙寫)
|
||||
|
||||
| 方案 | 做法 | 優 | 劣 |
|
||||
|------|------|----|----|
|
||||
| **A. records 表加 q 搜尋** | 給 `/records/search` 加 `q=` LIKE 掃 slots | 改動小 | records 吃不到 #7 的 Vectorize 語意;要另接一套語意=重造 #7 已有的輪子 |
|
||||
| **B. 改存 entry(取代 record)** | workflow metadata 改寫進 `entries`(`entry_type=workflow`),description 進可 embed 欄位 | 直接吃 #7 語意 + 降級閉環,零重造 | 既有 `u6u_list_workflows` 讀 record 要改;migration 成本 |
|
||||
| **C. 雙寫(record + entry)** ⭐ | 部署時**同時**寫 workflow_metadata record(保既有 list/get 不動)**+** 一個 `entry_type=workflow` 的 embeddable entry(給搜尋) | list/get 零回歸;搜尋吃 #7 語意;兩者解耦各司其職 | 一份資料兩處;要保證一致(部署原子性) |
|
||||
|
||||
**推薦:C(雙寫)**,理由:
|
||||
- **不回歸**:`u6u_list_workflows` / `u6u_get_workflow` 繼續讀 record,完全不動(降低框架級風險,守 C1)。
|
||||
- **吃現成語意**:搜尋走 entry → 直接複用 #7 的 `/entries/search?mode=semantic` + 降級 + capability_hint,**零重造**。
|
||||
- **解耦**:record=「我有哪些 workflow」(精確列舉,list 場景);entry=「找做某事的 workflow」(語意檢索,search 場景)。職責不同、欄位不同,本就該分。
|
||||
- 一致性風險可控:雙寫在同一個部署 API handler 內,entry 寫失敗不阻塞部署但回 warning(fire-and-forget + 可補建),對齊 #7 `embedOnWrite` 的 `waitUntil` 非阻塞慣例。
|
||||
|
||||
> **被否的 A**:records 加 q 只能 LIKE,要語意還是得自己接 Vectorize=把 #7 在 entries 做好的事在 records 再做一遍。違反「不重造輪子」。
|
||||
> **被否的 B**:取代 record 會逼 list/get 一起改,框架級風險放大,不值得。
|
||||
|
||||
---
|
||||
|
||||
## 3. R1:強制 description(落 API)
|
||||
|
||||
### 3.1 統一驗證點
|
||||
|
||||
> ⚠️ **實作期發現(2026-06-27,已讀 code)**:`POST /workflows/deploy` **在 cypher-executor 根本不存在**(route 清單只有 `/workflows/:name/executions`、`/workflows/resume`)。MCP `u6u_deploy_workflow.ts:22` 打 `http://cypher-executor/workflows/deploy` → **目前必 404**。意味 MCP 部署路徑現狀是壞的 / 從未端到端驗過。這影響「兩條路徑」的定義,見 §3.1a 待決。
|
||||
|
||||
description 強制**落在 cypher-executor 的部署端點**。實際部署端點有三個:
|
||||
- `POST /webhooks`(token 式匿名):description optional。
|
||||
- `POST /webhooks/named`(CLI `acr push`,具名):description optional → **改必填**。
|
||||
- `POST /workflows/deploy`(MCP 目標):**不存在(404)**。
|
||||
|
||||
#### 3.1a 待決:MCP 部署路徑怎麼收斂(新發現,需拍板)
|
||||
兩個方向:
|
||||
- **方向 ① MCP 改打 `/webhooks/named`**(推薦):MCP deploy 不再打死端點,改打 CLI 同一條 `/webhooks/named`(傳 name + graph + description)。→ **CLI/MCP 真正共用一條部署端點**(rule 07 薄殼一致的最強形態),死端點順手清掉,description 強制只需做在 `/webhooks/named` 一處。
|
||||
- **方向 ② 新建 `/workflows/deploy`**:補上這條 route 給 MCP 專用。→ 但會變成「兩條部署端點各做一次 description 強制」,且與 `/webhooks/named` 職責重疊(都是部署具名 workflow),違反「能力只實作一次」。
|
||||
|
||||
> **leo 拍板(2026-06-27 issue #8):方向①** ✅。CLI/MCP 共用一條部署端點=rule 07 最強形態;list 改讀 `GET /webhooks/named`(現成端點,回歸可控)。
|
||||
|
||||
**強制規則**:缺/空白 trim 後為空 → `400 { error: '<§3.2 定位訊息>', requires: 'description' }`。驗證是 API 行為(R1.3),薄殼不判空(守 rule 07)。
|
||||
|
||||
#### 3.1b 方向①實作期再發現:YAML→部署編排被寫在 CLI 介面層(藏的薄殼債)
|
||||
|
||||
讀 code 發現「MCP 改打 /webhooks/named」不是換 URL 就好——**`/webhooks/named` 吃的是 graph 物件,不是 YAML**。把 YAML 變 graph 的編排目前在 **CLI `push.ts` 介面層**做了一整段:
|
||||
1. `loadWorkflowYaml` + `parseTriplets`(解析 YAML flow → triplets)
|
||||
2. `POST /cypher/search`(triplets → 執行圖 graph)
|
||||
3. config 套節點、組 `{id, name, nodes, edges}` graph
|
||||
4. `POST /webhooks/named`(傳 graph)
|
||||
|
||||
而 MCP `u6u_deploy_workflow` 吃 `yaml_content` 字串、期待一個**吃 YAML 的 server 端點**(打 `/workflows/deploy` 傳 `Content-Type: application/yaml`)——這端點從來不存在(故 404)。
|
||||
|
||||
**張力**:方向① 若讓 MCP 在介面層複製 CLI 那 4 步編排 → **兩個薄殼各做一次 YAML→graph 編排 = 違 rule 07「能力只實作一次」**(正是薄殼原則要防的)。
|
||||
|
||||
**收斂選項(待總管定,§3.1c)**:
|
||||
- **①-a 最小修**:MCP 介面層複製 CLI 的 YAML→graph 步驟,打 /webhooks/named。→ 快,但複製編排=技術債(與方向①初衷「薄殼統一」自相矛盾)。
|
||||
- **①-b 編排下沉(正解)** ⭐:新增 API 端點 `POST /workflows/deploy`(這次**真的建**,但吃 YAML、職責是「YAML→graph→部署」完整編排),CLI 和 MCP 都只傳 YAML。→ 真正一處編排,兩薄殼都瘦。但要把 CLI push.ts 的編排搬進 API(較大重構,且碰 exposure_consent 流程)。
|
||||
- **①-c 折中**:先 ①-a 讓 MCP 通(解 404、issue #8 範圍內),①-b 編排下沉另開 issue(薄殼債獨立追)。
|
||||
|
||||
> 註:①-b 的 `/workflows/deploy` 與被否的「方向②」不同——②是「為 MCP 另開一條重複端點」,①-b 是「把編排下沉成唯一真相端點,CLI 也改用它」。前者增重複,後者消重複。
|
||||
|
||||
### 3.2 description 來源(Q2 定案:操盤 CC 據實生成、用戶可改)
|
||||
|
||||
> leo 翻案,但守住誠實精神。目標用戶 low-code,**不知道要填 description**;強迫填一個不懂的欄位=違北極星「不增加用戶負擔」。調和關鍵=分清兩種「生成」:
|
||||
|
||||
- ✅ **操盤的 CC 據實生成**:CC 剛幫用戶建這工作流,**最懂它串了什麼、做什麼** → 由 CC 寫一句真實的「這做什麼」(leo 例:「呼叫可以 Upsert Google Sheets」)。這是**真描述非假裝**,完全不違 mindset §7。
|
||||
- ❌ **介面層機械塞佔位**(從 name 複製、塞 `workflow_xxx` 預設)=假描述,**仍禁**(§3.2 原本防的就是這個,保留)。
|
||||
|
||||
**落地規則**:
|
||||
- **YAML `description:` 為主**:CC 寫 workflow YAML 時就據實填好 description(既有慣例,`registry/examples` 已示範)。
|
||||
- description **強制非空仍落 API**(R1 不變,§3.1 驗證點不動)。
|
||||
- 部署若收到空 description:**不是擋下逼用戶手填**,而是回明確訊息要求**操盤 CC 據實補一句**再部署(CC 是 description 的生成者,用戶可改)。錯誤訊息對齊此定位:「description 必填:請操盤的 AI 據實寫一句『這工作流能做什麼』(如「呼叫可 Upsert Google Sheets」),用戶可再改。」
|
||||
- **內容定位**:一句「這工作流**能做什麼**」,**不是寫文章**。供語意搜尋命中,要點是「做什麼」可被自然語言意圖匹配。
|
||||
- **仍禁**:介面層(CLI/MCP TS)機械從 name 生成佔位(守 rule 07 + 誠實,hook 7.x 範圍)。「據實生成」是操盤 CC 在寫 YAML 當下做的,不是介面層 deploy 時自動補。
|
||||
|
||||
---
|
||||
|
||||
## 4. R2:可搜的 entry + search_workflow
|
||||
|
||||
### 4.1 部署時寫 embeddable entry(雙寫的 entry 那半)
|
||||
部署成功後(record 寫完),cypher 端再寫一個 entry 到 KBDB:
|
||||
|
||||
```
|
||||
POST /kbdb/entries (經 cypher proxy,租戶隔離注 owner_id)
|
||||
{
|
||||
entry_type: "workflow",
|
||||
page_name: <workflow name>,
|
||||
content: <description>, // 被 embed 的主體
|
||||
metadata: {
|
||||
embed: true, // #7 精耕開關:只有標 true 才進 Vectorize
|
||||
workflow_id, name, deployed_at
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `metadata.embed:true` → 命中 #7 的 `embedOnWrite` 精耕條件,description 進 Vectorize(若模組開)。
|
||||
- 模組沒開 → entry 照樣存(D1),語意搜降級成 LIKE 仍能命中 content/name(不假綠)。
|
||||
- owner_id 由 cypher proxy 強制注入本租戶(沿用既有隔離,C4/R2.4)。
|
||||
|
||||
### 4.2 search_workflow 工具(薄殼)
|
||||
新 MCP 工具 `search_workflow(query)`,形態抄 `u6u_search_components`:
|
||||
|
||||
```
|
||||
search_workflow(query) →
|
||||
cypher GET /workflows/search?q=<query>&mode=semantic
|
||||
→ KBDB /entries/search?q=&owner_id=&source=&mode=semantic&entry_type=workflow
|
||||
→ mode=semantic 開:Vectorize 語意命中
|
||||
→ 沒開:降級 keyword(LIKE) + capability_hint「叫 CC 幫你開語義查詢」
|
||||
```
|
||||
|
||||
- cypher 加一條 `GET /workflows/search`(薄轉發到 KBDB `/entries/search`,限 `entry_type=workflow` + 本租戶 owner_id)。
|
||||
- MCP 工具把結果格式化(含 capability_hint 透傳給 AI,AI 看到就能主動問用戶開 Vectorize → R2.3)。
|
||||
- 命名:MCP 既有工具是 `u6u_*` 前綴(`u6u_search_components`)。本工具命名 `u6u_search_workflows`(複數對齊 `u6u_list_workflows`),對外描述「用自然語言找現成工作流」。
|
||||
|
||||
### 4.3 Vectorize 開啟(R2.3,不新造)
|
||||
完全沿用 #7:`acr init` 問 / `kbdb_embed:true` + `acr update` → deploy 建 Vectorize index。AI 從 search 回傳的 `capability_hint` 得知未開 → 主動問用戶要不要開。本 SDD **不碰** Vectorize 開關機制,只消費它。
|
||||
|
||||
---
|
||||
|
||||
## 5. R3:既有工作流回填
|
||||
|
||||
**推薦:下次部署強制 + 一次性 backfill 端點(提示式,不自動跑)**
|
||||
|
||||
- **下次部署強制**:R1 生效後,任何 re-deploy 都會被逼填 description → 自然回填(隨用隨補)。
|
||||
- **一次性 backfill**:加 `POST /workflows/backfill-search-entries`(限本租戶),把現有 workflow_metadata records 中**已有 description 的**補寫成 entry(讓它們可搜);**無 description 的**列出來回報「這些需要 re-deploy 補 description」,**不**自動編造描述(誠實)。
|
||||
- backfill 是 **AI/人主動呼叫**(CLI/MCP 暴露),**不掛 cron/輪詢**(C2 flag 紅線)。
|
||||
- 不破壞執行:entry 只供搜尋,workflow trigger 仍讀 WEBHOOKS KV / record,互不影響(R3.2)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 薄殼一致性(rule 07)
|
||||
|
||||
| 能力 | API(真相) | MCP 薄殼 | CLI 薄殼 |
|
||||
|------|------------|----------|----------|
|
||||
| 強制 description | cypher 部署端點驗證 | (deploy 工具透傳錯誤)| (push 透傳錯誤)|
|
||||
| 搜尋 workflow | cypher `/workflows/search` → KBDB `/entries/search` | `u6u_search_workflows`(本 SDD) | `acr workflow search`(R2.5,次階段,對稱補)|
|
||||
| backfill | cypher `/workflows/backfill-search-entries` | 可選暴露 | 可選暴露 |
|
||||
|
||||
齊的單位是「能力」不是「端點」(decisions-summary 已釐清):search 能力 MCP 先到位(AI 先用),CLI 對稱補可列次階段,不阻塞。
|
||||
|
||||
---
|
||||
|
||||
## 7. flag 安全自檢(C2)
|
||||
|
||||
- search_workflow=AI 收到自然語言意圖時**主動 call 一次**,無排程、無 webhook 觸發、無跨 repo fan-out。✅
|
||||
- backfill=人/AI 主動呼叫一次,非 cron。✅
|
||||
- 雙寫的 entry embed 走 `waitUntil` 非阻塞,是單次部署內的副作用,非輪詢。✅
|
||||
|
||||
---
|
||||
|
||||
## 8. 影響面(框架級,C1)
|
||||
|
||||
- **改 cypher-executor**:`/webhooks/named` + `/workflows/deploy` 加 description 強制;新增 `/workflows/search` + `/workflows/backfill-search-entries`;部署 handler 加雙寫 entry。
|
||||
- **改 MCP**:`u6u_deploy_workflow` 抓並傳 description;新增 `u6u_search_workflows`。
|
||||
- **改 KBDB**:可能不用改(複用 #7 `/entries/search` + `entry_type=workflow` 過濾;確認 `/entries/search` 支援 `entry_type` filter,若無則補一個 filter 參數——base 通用 filter,不寫死 workflow)。
|
||||
- **self-hosted 影響**:description 強制對所有用戶生效 → 回填策略(R3)讓既有資產平滑過渡,不一刀斷。
|
||||
- **不改**:workflow 執行/trigger 路徑、Vectorize 開關機制(複用 #7)、零件搜尋。
|
||||
|
||||
---
|
||||
|
||||
## 9. 拍板結果(leo 2026-06-27 issue #8,4 點全定)
|
||||
|
||||
1. **Q1 方案 C(雙寫)✅** — record 保 list/get 零回歸 + entry_type=workflow embeddable entry 吃 #7 語意,waitUntil 非阻塞。
|
||||
2. **Q2 description「操盤 CC 據實生成、用戶可改」✅(leo 翻案)** — 非「介面層不生成」也非「逼用戶手填」。強制非空仍落 API;空時要求**操盤 CC 據實補一句**(非介面層機械塞佔位,仍禁佔位)。定位=一句「能做什麼」非文章。詳見 §3.2。
|
||||
3. **Q3 回填「下次部署強制 + 提示式 backfill」✅** — 無 desc 列出待 re-deploy、不自動編造、不掛 cron。
|
||||
4. **Q4 補 base 通用 entry_type filter ✅** — 總管查證:`/entries/search` 目前**不支援** entry_type 過濾(只有 q/owner_id/source/mode),但 schema 有 entry_type 欄位 + 索引(`0001_base.sql:16-20`)。要改 **4 處**:`route`(entries.ts:43-77)/ `searchEntries` / `semanticSearch`(embed.ts)/ `kbdb-proxy`。**做成 base 通用 filter 不寫死 workflow**。
|
||||
|
||||
> **狀態:4 點拍定,已點頭實作。** 按 tasks.md Phase 1→6 推進,leo21c 端到端綠燈為完成標準。
|
||||
@@ -0,0 +1,82 @@
|
||||
# workflow-discovery — Requirements
|
||||
|
||||
> **來源**:InkStoneCo 總管 GitHub issue #8([地基1])。
|
||||
> **狀態**:草案,待 richblack/總管確認方向後才實作。
|
||||
> **建立**:2026-06-27
|
||||
> **白名單**:`.claude/hooks/pre-write-guard.sh` KNOWN_SDDS 已加 `docs/3-specs/workflow-discovery`(2026-06-27 issue #8 授權)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 問題陳述(北極星入口缺口)
|
||||
|
||||
北極星:**「AI 先查有沒有現成工作流 → 找到就執行它」**。這條的入口現在是斷的。
|
||||
|
||||
- **零件可被搜**(雖然目前只是 KV substring,非真語意,但有 `query` 介面):`u6u_search_components(query)` → `/components/search?q=`。
|
||||
- **工作流不可被搜**:只有 `u6u_list_workflows`(list / tag 過濾)與 `u6u_get_workflow`(按 ID)。沒有 `query` 入口。
|
||||
- **根因**:工作流的 metadata 沒有可語意比對的 `description` 欄位被穩定落庫。
|
||||
- workflow YAML **慣例上已有 `description:`**(`registry/examples/*/workflow.yaml` 就寫了),但:
|
||||
- 不強制(建工作流可不填)。
|
||||
- 兩條部署路徑落庫不一致(見 §3 現況核實)。
|
||||
- 即使有 description,存它的 `workflow_metadata` 是 KBDB **record**(按 template 精確查),不是可被 `/entries/search` 文字/語意搜的 **entry**。
|
||||
|
||||
**後果**:mira 那批工作流(門鈴/催辦/dashboard/閉環)建了也搜不到;對人也一樣——工作流多了會忘在哪。
|
||||
|
||||
---
|
||||
|
||||
## 2. 現況核實(2026-06-27,已讀 code)
|
||||
|
||||
| 事實 | 證據(檔案) |
|
||||
|------|------|
|
||||
| workflow YAML 已有 `description:` 慣例 | `registry/examples/webhook-to-http/workflow.yaml:2` |
|
||||
| CLI `acr push` → `POST /webhooks/named`,`description` 已接受但 **optional**(空字串 fallback) | `cypher-executor/src/routes/webhooks-named.ts:67,96` |
|
||||
| MCP `u6u_deploy_workflow` → `POST /workflows/deploy`,另存 `workflow_metadata` record,**slots 無 description**,只從 YAML 抓 `name` | `mcp/src/tools/u6u_deploy_workflow.ts:40-58` |
|
||||
| `workflow_metadata` record 走 `/records/search?template=`(精確 template 查,**無 q 文字搜尋**) | `mcp/src/tools/u6u_list_workflows.ts:26`、`kbdb/src/routes/records.ts:24` |
|
||||
| KBDB entries 已有真語意 search(issue #7):`/entries/search?mode=semantic`,未開 Vectorize → 降級 keyword + `capability_hint` | `kbdb/src/routes/entries.ts:43-76`、`kbdb/src/embed.ts` |
|
||||
| 「零件可語意搜」其實是 KV prefix + substring `includes(q)`,非真語意(code 自注 Phase 0) | `registry/src/actions/queryComponents.ts:88-132` |
|
||||
|
||||
---
|
||||
|
||||
## 3. 需求(issue #8 三任務 → 可驗收條目)
|
||||
|
||||
### R1:description slot,建工作流時強制填
|
||||
- **R1.1** workflow 部署時 `description` 為**必填**;空白/缺失 → 部署被擋(回明確錯誤,像零件那樣不給空白過)。
|
||||
- **R1.2** 兩條部署路徑(CLI `acr push` / MCP `u6u_deploy_workflow`)**一致強制**——不能一條擋一條放。
|
||||
- **R1.3** description 是**能力(API 行為)**,強制邏輯落在 API(cypher-executor 部署端點),不寫進薄殼介面層(守 rule 07)。
|
||||
|
||||
### R2:search_workflow(query) 工具
|
||||
- **R2.1** 補 MCP `search_workflow(query)`(命名對齊既有 `u6u_search_components` 形態)。
|
||||
- **R2.2** **優先語意搜尋**;KBDB 未開 Vectorize → **降級關鍵字(LIKE)** + 回 `capability_hint` 告知「叫 CC 幫你開語義查詢」(對齊 issue #7 閉環,不假裝有語義、不假綠)。
|
||||
- **R2.3** Vectorize 的開啟由 **AI 詢問用戶**觸發(`kbdb_embed:true` + redeploy 建 index),對齊 #7 既有開關,不新造機制。
|
||||
- **R2.4** 搜尋限**本租戶**(org_namespace / owner_id 隔離),不跨租戶洩漏。
|
||||
- **R2.5**(對稱補強,選做)同一機制可順帶讓 CLI 有對等 `acr workflow search`(薄殼一致目標,rule 07 §5;可列為次階段)。
|
||||
|
||||
### R3:既有工作流回填策略
|
||||
- **R3.1** 既有無 description 的 workflow_metadata:設計回填/遷移策略——下次部署強制補、或一次性 migrate 端點提示補。
|
||||
- **R3.2** 回填不可破壞既有 workflow 執行(description 只影響可發現性,不影響 trigger)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 跨專案約束(頂層鐵律,issue #8 明列)
|
||||
|
||||
- **C1 框架級慎改**:改了影響**全部 arcrun 用戶**(含 self-hosted)→ 先 SDD 確認方向再實作。
|
||||
- **C2 flag 紅線**:search 是 **AI 主動 pull**,**不掛輪詢**、不掛 Actions/cron fan-out。
|
||||
- **C3 範圍邊界**:「沒想到要找」那一半(釘選/常用清單)是 **mira 私人環境**的事,另開 mira issue,**不在本 repo**。
|
||||
- **C4 薄殼鐵律**:能力(強制填、搜尋)落 API;CLI/MCP 只暴露(rule 07)。
|
||||
- **C5 誠實不假綠**:未開 Vectorize 就老實降級 + hint,不假裝語義(mindset §7、對齊 #7)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 非目標(明確不做)
|
||||
|
||||
- ❌ 把零件搜尋升級成真語意(那是 registry 的 Phase 2,另案;本 SDD 只管 workflow)。
|
||||
- ❌ 釘選/常用工作流清單(C3,mira 私人環境)。
|
||||
- ❌ 跨租戶/公庫工作流市場搜尋(workflow 目前是私有 namespace 資產;公庫化是更大的另案)。
|
||||
- ❌ 自動觸發式 search(C2 flag 紅線)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 開放問題(design 要回答 / 待人拍板)
|
||||
|
||||
- **Q1**:workflow metadata 該從 **record 改存成 entry**(吃 #7 語意)、還是 **records 表自己加 q 搜尋**、還是**雙寫**?(design §2 給方案比較與推薦)
|
||||
- **Q2**:強制 description 對既有工作流是「下次部署才強制」還是「立即 migrate」?(R3,design 給推薦)
|
||||
- **Q3**:description 從 YAML `description:` 解析強制,還是部署 API 參數強制,還是兩者?(兩條路徑統一點在哪)
|
||||
@@ -0,0 +1,64 @@
|
||||
# workflow-discovery — Tasks
|
||||
|
||||
> **狀態**:方向待確認,**尚未實作**(全部 `[ ]`)。確認後才動 code。
|
||||
> 對應 `design.md`。**tasks.md 是唯一進度來源**,每完成一個立刻標 `[x]`,不批次。
|
||||
> 建立:2026-06-27(issue #8)
|
||||
|
||||
---
|
||||
|
||||
## Phase 0:方向確認(前置,擋住所有實作)
|
||||
|
||||
- [x] 0.1 SDD 三件式回報到 issue #8 comment,列關鍵決策(方案 C 雙寫 / YAML description 為準 / 提示式回填)
|
||||
- [x] 0.2 等總管/richblack 點頭;拍板 design §9 的 4 個待決點 — **leo 2026-06-27 全拍定,Q2 翻案(CC 據實生成 vs 介面層不生成)已吸收進 design §3.2**
|
||||
- [x] 0.3 實作前核實 `/entries/search` 是否支援 `entry_type` filter — **總管查證:不支援(只有 q/owner_id/source/mode),schema 有欄位+索引,要改 4 處(route/searchEntries/semanticSearch/kbdb-proxy),做 base 通用 filter**
|
||||
|
||||
---
|
||||
|
||||
## Phase 1:強制 description(R1,Q2 定案:CC 據實生成、用戶可改)
|
||||
|
||||
- [x] 1.1 cypher `POST /webhooks/named`:`description` 改必填,trim 後空 → 400 + 可操作錯誤訊息(定位:要求操盤 CC 據實寫一句「能做什麼」,非逼用戶手填、非介面層機械塞)— webhooks-named.ts 加驗證,tsc 綠
|
||||
- [⏸] 1.2/1.3 MCP deploy 改走 /webhooks/named(方向①,leo 拍定)— **卡在 ①-a/b/c 子決策**(design §3.1b/c):實作期發現 /webhooks/named 吃 graph 非 YAML,YAML→graph 編排現在寫在 CLI push.ts 介面層;MCP 複製=違 rule 07。等總管定 ①-a(複製)/①-b(編排下沉新 /workflows/deploy 吃 YAML,CLI 也改用)/①-c(先 a 通、b 另開 issue)。**注**:無論哪個,MCP 最終打 /webhooks/named(已強制 description,1.1 完成)→ description 強制目標三選項都達成。
|
||||
- [x] 1.3b(方向①前置,三選項共需)`GET /webhooks/named` 補回 description/created_at/cron_expr 欄位,讓 MCP list 改讀本端點時欄位齊 — webhooks-named.ts,tsc 綠
|
||||
- [ ] 1.4 驗證:兩條路徑各跑一次「無 description 部署」→ 都被擋(端到端,非只 tsc)— CLI 路徑已可驗,MCP 待 ①-a/b/c 收
|
||||
|
||||
## Phase 2:可搜 entry 雙寫(R2 資料層)
|
||||
|
||||
- [x] 2.1 cypher 部署 handler:record 寫完後雙寫一個 `entry_type=workflow` entry(content=description、metadata_json.embed:true、owner_id=apiKey),`waitUntil` 非阻塞 — webhooks-named.ts 加 writeWorkflowSearchEntry helper(注意:KBDB 用 metadata_json 字串非 metadata 物件)。tsc 綠
|
||||
- [x] 2.2 補 KBDB `/entries/search` 的 `entry_type` filter(base 通用,不寫死 workflow)— 改 4 處:searchEntries(entry-crud.ts) + semanticSearch(embed.ts,entry_type 已 index) + route(entries.ts) + cypher kbdb-proxy `/kbdb/search` 透傳。kbdb+cypher tsc 綠
|
||||
- [ ] 2.3 驗證:部署一個帶 description 的 workflow → KBDB 查得到對應 entry(owner_id 正確)
|
||||
|
||||
## Phase 3:search_workflow 工具(R2 介面層)
|
||||
|
||||
- [x] 3.1 cypher 新增 `GET /workflows/search?q=&mode=`:轉發 KBDB `/entries/search`(限 entry_type=workflow + 本租戶 owner_id,預設 mode=semantic 自動降級)— webhooks-named.ts。tsc 綠
|
||||
- [x] 3.2 MCP 新增 `u6u_search_workflows(query)`:呼叫 3.1,格式化結果,透傳 `capability_hint`(AI 看到可主動問用戶開 Vectorize)— 新檔 + registry 註冊。tsc 綠
|
||||
- [ ] 3.3 驗證 mode=keyword(Vectorize 未開):LIKE 命中 + 回 capability_hint「叫 CC 幫你開語義查詢」
|
||||
- [ ] 3.4 驗證 mode=semantic(Vectorize 開,需 self-hosted leo21c):語意命中,限本租戶
|
||||
- [ ] 3.5 租戶隔離驗證:A 租戶搜不到 B 租戶的 workflow(count=0)
|
||||
|
||||
## Phase 4:既有工作流回填(R3)
|
||||
|
||||
- [x] 4.1 cypher `POST /workflows/backfill-search-entries`(限本租戶):有 description 的 record → 補寫 entry;無 description 的 → 列出回報,不自動編造 — webhooks-named.ts,tsc 綠
|
||||
- [ ] 4.2 backfill 經 CLI/MCP 暴露為主動指令(非 cron,守 C2)
|
||||
- [ ] 4.3 驗證:對既有 workflow 跑 backfill → 有 desc 的可搜、無 desc 的被正確列出待補
|
||||
|
||||
## Phase 5:薄殼對稱補(R2.5,次階段,可獨立驗收)
|
||||
|
||||
- [ ] 5.1 CLI `acr workflow search <query>`:對等 MCP 工具(同一 cypher 端點)
|
||||
- [ ] 5.2 驗證:CLI/MCP 同 query 回同一組結果(底層同端點,差異只來自介面慣例)
|
||||
|
||||
## Phase 6:收尾
|
||||
|
||||
- [ ] 6.1 tsc 全綠(cypher / mcp / cli / kbdb 受影響者)
|
||||
- [ ] 6.2 部署 + 端到端實證(leo21c 帳號跑強制填 + 搜尋 + 回填,收客觀證據非自報)
|
||||
- [ ] 6.3 issue #8 comment 回報端到端綠燈證據;由實證決定結案時機(待端到端綠才 close)
|
||||
- [ ] 6.4 同步更新 design.md(若實作中發現偏差)+ wiki status
|
||||
|
||||
---
|
||||
|
||||
## 跨任務鐵律提醒
|
||||
|
||||
- 強制填 / 搜尋 / 回填全是**能力 → 落 API**;CLI/MCP 只暴露(rule 07)。
|
||||
- **不假綠**:未開 Vectorize 就老實降級 + hint,不假裝語義(mindset §7)。
|
||||
- **不自動編造 description**:強制是逼真的描述,自動填 = 假裝有(誠實)。
|
||||
- **flag 紅線**:search/backfill 都是主動 pull,無 cron/輪詢/fan-out(C2)。
|
||||
- 框架級改動 → 端到端實證(leo21c)才算完成,不是 tsc 綠就宣布。
|
||||
Reference in New Issue
Block a user