---
name: arcrun-mindset
description: >-
  在 Arcrun 上做任何事時使用（用戶說「幫我用 Arcrun 做 X」「用 arcrun 寫一個工作流」「把 X 自動化」）。
  Arcrun 是跑在 Cloudflare 上的工作流引擎——你用 `>>` 寫「意圖」，系統告訴你有哪些現成零件與 recipe，
  你只填 payload，不必自己寫程式。**不要上網搜 Arcrun 文件**（網路上沒有），也不要自己猜 YAML 格式：
  先讀本 skill，再用 `acr` 指令（或 MCP 工具）查現成零件。
  涵蓋：意圖工作流語法、四份實跑過的範本、零件 vs recipe 的分別、缺件的兩條路、已知的坑。
---

# Arcrun：怎麼寫意圖工作流

> **你已經配備 Arcrun**（此專案裝了 `acr` CLI，可能另有 `arcrun_*` MCP 工具）。
> **別上網找文件**——網路上沒有 Arcrun 的文件，找到的都是錯的。答案都在本 skill 與 `acr` 指令裡。

## 先做這三件（照順序）

1. `acr whoami` — 確認連到哪個帳號（**勿自行 curl 猜帳號 URL**）
2. 讀本 skill 下面的語法與範本 → 寫出 `>>` 意圖
3. `acr parts`／`acr recipe list`（或 `acr search <關鍵字>` 一次掃全部）— 確認零件與 recipe 真的存在

**卡住時**：`acr search <關鍵字>` 跨類搜尋；有 MCP 就 `arcrun_get_skill('INDEX')` 拿全館導航。

---

## 0. 一句話世界觀

**Arcrun 裡幾乎所有東西都是工作流（workflow）。** 工作流 ＝ 一張紙，寫「用哪些零件、什麼順序、什麼條件」。
你大部分時間在**寫紙、改紙**，不是在造新零件、也不是自己寫腳本。

**Arcrun 只有三種東西，先分清楚就不會做歪：**

| 東西 | 是什麼 | 你能做的 |
|---|---|---|
| **工作流（workflow）** | 把零件／recipe 串起來的純文字流程 | **預設就寫這個**，自由寫 |
| **recipe** | 打「一個固定外部 API」的設定（endpoint／header／body 模板） | 自由寫、**而且該投稿**（缺就自己補） |
| **零件（component）** | WASM 程式（流程控制／資料處理／`http_request`／auth），固定一小套 | **你不自製**，走 PR 由維護者管 |

> **一句話判準**：打一個固定外部 endpoint → 寫 **recipe**；流程控制／資料處理／通用 HTTP → 用既有**零件**；其他 → 寫**工作流**串起來。

---

<!-- 以下正文由 registry/skills/write_intent_workflow.md 於建置期複製而來（單一真相源）。
     不要直接編輯本段——改 registry 那份，然後跑 `npm run build:harness`。 -->

## 1. 意圖工作流的語法

一串「誰接誰」，每行一個關係：

```
<節點A> >> <邊> >> <節點B>
```

- **節點**＝一個步驟。用你想得到的名字（中文可以），**不必是真實零件名**
- **邊**＝什麼情況下往下走

## 2. 邊有這些

| 邊 | 意思 | 真例 |
|---|---|---|
| `ON_SUCCESS` | 上一步成功就往下 | `input >> ON_SUCCESS >> prep` |
| `對每個 <變數>` | 上一步產出清單，逐項處理（FOREACH）| `parse_card >> 對每個 block >> post_block` |
| `ON_TRUE` / `ON_FALSE` | 條件成立／不成立各走一條（配 `if_control`）| `判斷有沒有新資料 >> ON_TRUE >> 傳到 telegram` |
| `ON_BRANCH`＋`branch:` | 依標籤選路（配 `switch` 每個 case、`try_catch` 的 try/catch）| `my_switch >> ON_BRANCH(branch_active) >> 處理啟用` |

### 2.1 條件分支怎麼寫（2026-08-01 起引擎支援）

**需要判斷時，用分支邊，不要寫 `code` 判斷。**
三顆流程控制零件都輸出 `data.branch` 標籤，引擎依標籤選路：

| 零件 | 輸出的標籤 | 接法 |
|---|---|---|
| `if_control` | `"true"` / `"false"` | `ON_TRUE`／`ON_FALSE` 各一條 |
| `switch` | 你在 `cases[].branch` 取的名字（沒中則 `default_branch`）| 每條路一條 `ON_BRANCH`，邊上標 `branch` |
| `try_catch` | `"try"`（沒錯）／`"catch"`（有錯）| 兩條 `ON_BRANCH`，標 `try` 與 `catch` |

```
判斷有沒有新資料 >> ON_TRUE >> 傳到 telegram
判斷有沒有新資料 >> ON_FALSE >> 結束
```
中文語意詞亦可：「成立時」＝`ON_TRUE`、「否則」＝`ON_FALSE`。

💡 **不必背**：查零件時回應會附 `branch_hint`（有哪些標籤、用哪些邊型、可照抄的範例），
照著接就對了。

⚠️ 仍然**不要寫 `ON_FAILURE`**（沒有這種邊；要處理失敗用 `try_catch` ＋ `ON_BRANCH(catch)`）。

### 2.2 怎麼確認分支真的走對了（**別看不懂就以為壞掉**）

分支工作流「有沒有成功」看兩件事，**不是看某條沒走的路沒有輸出**：

1. **`verdict`**：`GET /workflows/<name>/executions?limit=1`
   → `data.executions[0].verdict === "success"` 就是成功了。
2. **`trace` 裡有沒有出現該走的節點**：走 TRUE 路時 FALSE 路的節點**本來就不該出現**
   ——**那是正確行為，不是失敗**。

```
# 條件成立 → 只有 true 那條的節點在 trace
{"amount": 5000}  → if_control 回 branch="true"  → 走 ON_TRUE 那條
{"amount": 100}   → if_control 回 branch="false" → 走 ON_FALSE 那條
```

🔴 **實撞（2026-08-01 考試）**：有考生的分支工作流**其實完全正常**
（`amount=5000`→true、`amount=100`→false 都對），但它以為「跑不通」而放棄改寫成 code。
**看到只有一條路有輸出＝分支正在正確運作**，不要因此判定失敗。

## 3. 第一個節點固定是 `input`

所有真範本都以 `input` 起頭——那是「觸發時帶進來的資料」。

---

## 4. 真範本（照抄結構、改內容）

> 以下四份**全部是實際部署且 `verdict=success` 的 workflow**，不是簡化示範。
> 用 `acr logs <name>`（有 MCP 則 `arcrun_get_workflow(<name>)`） 可以拿完整定義。

### A. 最短：取資料 → 處理　（`graph_neighbors`）
```
input >> ON_SUCCESS >> fetch_triplets
fetch_triplets >> ON_SUCCESS >> bfs_neighbors
```

### B. 長鏈：多次查詢 → 組裝 → 問 AI → 收尾　（`rag_chat`）
```
input >> ON_SUCCESS >> prep
prep >> ON_SUCCESS >> kw_search
kw_search >> ON_SUCCESS >> sem_search
sem_search >> ON_SUCCESS >> fetch_triplets
fetch_triplets >> ON_SUCCESS >> fetch_blocks_a
fetch_blocks_a >> ON_SUCCESS >> assemble
assemble >> ON_SUCCESS >> ask_llm
ask_llm >> ON_SUCCESS >> finalize
```
`prep` 前處理／`assemble` 組 prompt／`finalize` 收拾回應——三個常見的整形節點。

### C. 一節點分岔兩條 FOREACH　（`rag_ingest_card`）
```
input >> ON_SUCCESS >> parse_card
parse_card >> 對每個 block >> post_block
parse_card >> 對每個 rel >> post_triplet
```
同一節點可有多條出邊，各自處理不同清單。

### D. 混合：直線 ＋ 兩段 FOREACH　（`rag_takedown_direct`）
```
input >> ON_SUCCESS >> prep
prep >> ON_SUCCESS >> list_dead_blocks
list_dead_blocks >> ON_SUCCESS >> build_deprecations
build_deprecations >> 對每個 dead_entry >> deprecate_entry
build_deprecations >> ON_SUCCESS >> list_triplets
list_triplets >> ON_SUCCESS >> pick_dead_triplets
pick_dead_triplets >> 對每個 dead_record >> deprecate_triplet
```
`build_deprecations` 同時有 FOREACH 出邊與 `ON_SUCCESS` 出邊——
前者處理清單、後者繼續主線。

---

## 5. 節點怎麼命名（照真範本的模式，查詢較容易媒合）

| 意圖 | 模式 | 真例 |
|---|---|---|
| 前處理／正規化 | `prep` | `rag_chat.prep` |
| 取一批資料 | `fetch_*`／`list_*` | `fetch_triplets`／`list_dead_blocks` |
| 搜尋 | `*_search` | `kw_search`／`sem_search` |
| 解析／切塊 | `parse_*` | `parse_card` |
| 寫入 | `post_*` | `post_block`／`post_triplet` |
| 組裝 | `assemble`／`build_*` | `assemble`／`build_deprecations` |
| 問 AI | `ask_llm` | `rag_chat.ask_llm` |
| 收尾整形 | `finalize` | `rag_chat.finalize` |

---

## 6. 寫完一定要查（**不要直接部署**）

```bash
curl -s -X POST https://arcrun-cypher-executor.<subdomain>.workers.dev/cypher/search \
  -H 'content-type: application/json' -H 'X-Arcrun-API-Key: <namespace>' \
  -d '{"triplets":["input >> ON_SUCCESS >> fetch_data","fetch_data >> ON_SUCCESS >> notify"]}'
```

回應的每個節點會有：

| status | 意思 | 你該做什麼 |
|---|---|---|
| `found` | 有這個節點。`source: component` 附 `input_schema`（怎麼填 payload）與 `success_rate`；`source: recipe` 附 description/endpoint | **只填 payload** |
| `not_found` | **兩庫（零件 registry＋recipe 庫）都查過，確定沒有** | 照 `suggestion` 欄走：缺 API → 寫 recipe（skill `write_recipe`）；缺計算能力 → 投稿零件 PR（skill `add_new_wasm_component`）。`similar_components`/`similar_recipes` 是相近候選——先看有沒有現成的能直接用 |
| `unknown` | 查不到 registry | **不代表不存在**，別據此改寫成 code |

> 註（2026-07-31）：`/cypher/search` 曾對任何節點名都回假 `found`，已修為真查兩庫。
> 舊實例（未更新部署）仍可能假 found——status 可信度以該實例部署版本為準。

---

## 7. 常犯的錯

1. **用不存在的邊**（`ON_FAILURE`）→ 沒有這種邊；要處理失敗用 `try_catch` ＋ `ON_BRANCH(catch)`
   ⚠️ `ON_TRUE`／`ON_FALSE`／`ON_BRANCH` **是存在的**（2026-08-01 起），見 §2.1——
   本行以前寫「ON_TRUE 不存在」是舊世代，已更正
2. **第一個節點不是 `input`**
3. **把 recipe 當零件寫**——`telegram_send`／`gmail`／`kbdb_get` 是 **recipe** 不是零件
   → 寫成 `http_request` ＋ 該 recipe
4. 🔴 **查詢回 `not_found` 就改寫成 `code` 節點**
   → 那叫「腹語術」（表面用 Arcrun、實際全寫 JS）。正解：缺 API 寫 recipe、缺能力投稿零件。
   `code` 只用在**局部整形**（例：剝掉 LLM 回應的雜訊），不用來取代零件與流程控制。

---

## 8. 相關

- 完整版指引與十題考卷（含 haiku 實測 10/10）：
  頂層 repo `system-dev/docs/3-specs/arcrun-usable/`
- 下一步該讀哪支 skill（需 MCP）：`arcrun_list_skills()`
  - 定期掃資料 → `build_watcher_workflow`
  - RAG 檢索問答 → `rag_with_arcrun`
  - workflow 卡住不動 → `debug_paused_workflow`


---

## 9. 資源去哪取（不要自己重造 Arcrun 已有的）

| 你想知道 | 跑這個 |
|---|---|
| 有哪些零件可用 | `acr parts` |
| 某零件的設定範本 | `acr parts scaffold <name>` |
| 有哪些 recipe | `acr recipe list`／`acr recipe search <關鍵字>` |
| 支援哪些服務的認證 | `acr auth-recipe list` |
| 某服務認證要哪些 credential ＋ 範例 | `acr auth-recipe scaffold <service>` |
| **一次掃全部**（零件／recipe／auth-recipe／workflow） | `acr search <關鍵字>` |
| 已部署的 workflow | `acr list` |
| 某次執行為什麼失敗 | `acr logs <workflow>` |
| 工作流語法、指令 | `acr --help` |

**先查再動手**——Arcrun 多半已經有你要的零件／recipe／認證，不要自刻。

## 10. 做出來以後：驗證 → 部署

```bash
acr validate <workflow>.yaml   # 先驗，別直接部署
acr push <workflow>.yaml       # 部署（暴露動作，見 §12）
acr run <workflow>             # 觸發一次，看實際結果
acr logs <workflow>            # 看執行紀錄／失敗原因
```

需要 credential（API key／token）時：`acr auth-recipe scaffold <service>` 看要哪些，
明確告訴使用者去哪取得、怎麼 `acr creds push`。
🔑 **金鑰只拿名字**：workflow／recipe 裡只寫 `{{credential.<名字>}}`，
**真身絕不寫進定義檔**（執行前才由系統回填）。

## 11. Arcrun 是你（AI）用的工具，不是工具回頭呼叫 AI

需要智慧判斷／自然語言轉換時，**你自己做**，再呼叫工作流執行確定性的下一步。
**不要在工作流中間放零件回頭呼叫 LLM**——Arcrun 的大腦就是操盤的你。
（唯一例外：`ask_llm` 這種「內容生成本身就是流程的一步」，見範本 B。）

## 12. 把東西開放給別人用 ＝ 要使用者明示同意

`acr push`（部署 workflow）與 `acr recipe push`（投稿 recipe）會讓資料／能力**可被外部呼叫**：
- 停下來，明確告訴使用者「這會讓 X 可被外部呼叫」，要他同意。**不替他決定公開。**
- 非互動環境（你直跑）遇到 → 停，把完整指令印給使用者自己貼上跑，絕不自己塞 confirm 假裝同意。
- Arcrun 可提供保護（要求呼叫者帶 key／限流）——提醒使用者。

## 13. Arcrun 不替你做授權判斷

API 打不打得通由發 key 的服務決定。401／403 是對方服務在行使授權，**不是 Arcrun 的 bug、不是你做錯**。
不要在 Arcrun 裡建「允許／禁止某 endpoint」的二次授權清單。

## 14. 誠實（最重要）

- **不假綠**：沒打通就誠實說。缺 credential 打不到 2xx → 標「未驗收：缺 X」，不 mock 充綠燈。
- **不假裝防偽／不代替人類確認**有風險的動作（暴露資料）。
- **完成 ＝ 客觀證據**（HTTP 2xx ＋ trace），不是口頭「做好了」。

---

## 動手前的自檢清單

1. 我把意圖寫成 `>>` 串了嗎？（還是直接跳去寫 YAML／寫程式）
2. 我查過 `acr search` / `acr parts` / `acr recipe list` 了嗎？
3. 查詢回 `not_found` 時，我走的是 recipe／零件 PR 兩條路，**還是偷偷改寫成 `code`**？（後者＝腹語術）
4. 我是不是讓工作流回頭呼叫 AI 做判斷？（是 → 改成我自己做）
5. 這動作會把資料開放給別人嗎？（會 → 要使用者明示同意）
6. 我有沒有假裝（假綠／假防偽／代替人類確認）？（有 → 停，誠實標明）
