# Tasks — Component Registry Canon

> 對應 SDD：[design.md](design.md)
> 上次更新：2026-05-07

**狀態 legend**：`[ ]` 待辦 / `[🔄]` 進行中 / `[x]` 完成

---

## Phase 0：前置（已完成）

- [x] 0.1 u6u-mcp Zod 4 → Zod 3 降版修 tools/list `_zod undefined` bug（2026-05-07）
- [x] 0.2 u6u-mcp service binding `inkstone-component-registry` → `arcrun-registry`（2026-05-07）
- [x] 0.3 確認 `mcp.finally.click/mcp/mcp` 端對端通，tools/list 回 14 個 tool（2026-05-07）

---

## Phase 1：Backfill Index（半天，立即見效）

- [x] 1.1 探查 registry 既有 endpoint：發現
  - 既有 `POST /components` 強制要 wasm bytes（multipart 或 base64），跑沙盒驗收 + 寫 R2 + 寫 KV
  - cypher-executor 已不從 R2 動態載 wasm（line 32 標 R2 路徑作廢，零件用獨立 Worker URL）
  - 結論：R2 是 legacy，registry 真正用途是 metadata 索引給 AI 搜尋
  - 決策：**加新 endpoint `POST /components/index-only`** 接 contract（無 wasm、無沙盒），專供 backfill 跟「已部署但未索引」零件用
- [x] 1.1.1 加 `src/actions/indexOnlyComponent.ts`（metadata-only 寫 KV，冪等）
- [x] 1.1.2 加 `src/routes/components.ts` 的 `POST /index-only` route
- [x] 1.1.3 部署 + smoke test（contract 驗證 + 錯誤處理通過）
- [x] 1.2 寫 `matrix/arcrun/registry/scripts/backfill-index.mjs`（zero-build node script，用 js-yaml）
- [x] 1.3 dry-run 確認 30 個 component 全 parse 通
- [x] 1.4 跑真 backfill（過程中發現並修了兩個 schema 問題）：
  - schema enum `category` 補 `auth` / `ai` / `platform`（types.ts）
  - `max_cold_start_ms` 上限放寬 50 → 500（auth/ai 含 crypto 需要）
  - `no_network_syscall` / `no_filesystem_syscall` 改 optional
  - `max_size_kb` 上限放寬 2048 → 8192
  - index-only route 對缺 gherkin/description/tags 的零件補 placeholder（不擋索引）
- [x] 1.5 驗證：MCP `u6u_search_components("kbdb")` 回 3 個零件（kbdb_ingest / kbdb_create_block / kbdb_patch_block）
- [ ] 1.6 驗證：`acr parts list` CLI 端對端能列
- [x] 1.7 驗證：registry KV 30 entries（30 created + 30 idx 共 60 keys）

---

## Phase 1.5：砍 R2 dead storage（先於 Phase 2，清架構斷層）

> 2026-05-07 加入。R2 wasm 路徑早已 dead（cypher-executor 不從 R2 讀），保留只會誤導 AI。
> SDD design.md 的「Phase 5 用戶自製零件 R2 上傳」一併廢止。

- [x] 1.5.1 改 `submitComponent.ts`：移除 R2 寫入段落，保留 KV 寫入
- [x] 1.5.2 移除 `wrangler.toml` 的 `[[r2_buckets]] WASM_BUCKET` binding
- [x] 1.5.3 移除 `types.ts` Bindings 的 `WASM_BUCKET: R2Bucket`
- [x] 1.5.4 既有 `wasm_r2_key` 欄位保留為 deprecated（queryComponents 仍會讀 legacy record）
- [ ] 1.5.5 廢止 `arcrun-wasm` R2 bucket（30 天觀察期後 → 2026-06-07 之後 `wrangler r2 bucket delete`）
- [x] 1.5.6 部署 + smoke test：search 端對端通過（kbdb 找到 3 個零件）
- [x] 1.5.7 cypher-executor 補清（2026-06-04 richblack 確認）：當初 1.5.2/1.5.3 只清 registry，cypher-executor 的同類 R2 殘留一併移除
  - `cypher-executor/wrangler.toml`：移除 `[[r2_buckets]] WASM_BUCKET`
  - `cypher-executor/wrangler.test.toml`：移除 R2 mock
  - `cypher-executor/src/types.ts`：移除 `WASM_BUCKET: R2Bucket`
  - `cypher-executor/src/lib/constants.ts`：修正過時註解（不再說「從 R2 讀取」）
  - 動機：R2 綁信用卡與 open source 零費用核心衝突；tsc --noEmit 通過
  - CLI `acr init` 的 R2 → 見 1.5.8（壓測報告出來後已處理）
- [x] 1.5.8 CLI R2 全清（2026-06-04，依壓測報告 docs/壓測報告.md #3#4）：R2 綁卡違背開源免費 + bucket 名非法證明從未跑通
  - `cli/src/lib/deploy.ts`：移除 `REQUIRED_R2_BUCKET`；新增 `stripOfficialOnlyBindings()`（注入時 strip routes/r2/ai）
  - `cli/src/commands/init.ts`：移除 `ensureR2Bucket` 呼叫 + `wasm_bucket` config + token 提示去 R2 Edit
  - `cli/src/lib/cf-api.ts`：移除 `ensureR2Bucket()`
  - `cli/src/lib/config.ts`：移除 `wasm_bucket?` 欄位
  - `cli/src/commands/validate.ts`：錯誤文案去 WASM_BUCKET 命名誤導
  - 同時修阻斷 #1#2（routes/AI 寫死 arcrun.dev）：strip 在 deploy.ts 注入暫存副本時做，不刪 repo 內 toml（官方 prod CI 仍需 routes）
  - 詳見 .agents/specs/arcrun/sdk-and-website/self-hosted-init.md §7.5

## Phase 2：部署即註冊（1-2 天）

- [x] 2.1 選擇方案：CI step（github actions）— 在 wrangler deploy 之後 curl `/index-only`
- [x] 2.2 寫 `registry/scripts/register-component.sh`（本地 + CI 共用 SSOT，python3 + pyyaml 解 YAML，curl POST registry）
- [x] 2.3 改 `.github/workflows/deploy.yml` tier1 deploy step 後加 "Register component in registry" step（degraded mode：失敗只 warning）
- [x] 2.4 本地驗 `bash scripts/register-component.sh kbdb_ingest` → 200 + already_indexed
- [ ] 2.5 真正 push 一個新零件驗 CI hook 端對端（需要等下次新增零件時驗）
- [ ] 2.6 文件化：`docs/contributing-components.md`「新增零件的標準流程」
- [ ] 2.7 廢止 `u6u_publish_component` tool 的「需手動 publish」假設（rebrand 一起做）

---

## Phase 3：Discoverability（半天）

- [ ] 3.1 改 GitHub `richblack/arcrun` README
  - 移除「21 個零件」這種寫死數字
  - 加「跑 `acr parts list` 或 MCP search 看當前清單」
  - 加 badge：`![components](https://registry.arcrun.dev/badge/components.svg)`
- [ ] 3.2 加 `matrix/arcrun/registry/src/routes/badge.ts`
  - GET `/badge/components.svg` 回 shields.io 格式 SVG
  - count 從 KV 即時 query
  - cache 1 分鐘（`Cache-Control: max-age=60`）
- [ ] 3.3 改 MCP `u6u_get_component_guide` tool（之後改名 `arcrun_*`）
  - 開頭加「鐵律：動工前必須先 search_components，找不到才 publish」
- [ ] 3.4 onboarding kit GitHub template repo（建議名 `arcrun-quickstart`）
  - 三件套：CLAUDE.md / `.cursor/rules/arcrun.mdc` / AGENTS.md
  - 強制：「呼叫 Claude/任何 AI 前，先 list MCP tools；arcrun MCP 已連線時，**禁止用 Python 直打 HTTP API**」
  - 內附範例 hello workflow 跟 component
- [ ] 3.5 寫 onboarding doc：`docs/onboarding-third-party-engineer.md`
  - 第三方工程師如何 30 秒內讓 AI 學會用 arcrun

---

## Phase 4：u6u → arcrun Rebrand（1 天，最後做）

> 規劃做完 Phase 1-3 驗證 OK 才動 rebrand，避免邊改邊驗。

### 4.1 Repo & Worker
- [ ] 4.1.1 `git mv matrix/u6u-mcp matrix/arcrun-mcp`（或 cp + rm，視 git history 偏好）
- [ ] 4.1.2 改 `matrix/arcrun-mcp/wrangler.toml`：
  - `name = "u6u-mcp"` → `name = "arcrun-mcp"`
  - 加 route `mcp.arcrun.dev/*`，舊 `studio.finally.click/mcp*` 保留 1 個月
- [ ] 4.1.3 改 `package.json`：`@inkstone/u6u-mcp-worker` → `@arcrun/mcp-worker`

### 4.2 Tool 前綴改名
- [ ] 4.2.1 14 個 tool 檔案 rename：`u6u_*.ts` → `arcrun_*.ts`
- [ ] 4.2.2 每個 tool 內部 `server.tool("u6u_xxx", ...)` 改 `server.tool("arcrun_xxx", ...)`
- [ ] 4.2.3 `src/tools/registry.ts` import 路徑全改
- [ ] 4.2.4 `src/index.ts` `serverInfo.name` 從 `u6u-mcp-server` 改 `arcrun-mcp-server`

### 4.3 文件
- [ ] 4.3.1 README.md 全文 u6u → arcrun
- [ ] 4.3.2 GUIDE.md 同上
- [ ] 4.3.3 GitHub `richblack/arcrun` README 補 MCP 段落（之前沒提）
- [ ] 4.3.4 任何提到 `u6u-mcp` / `mcp.finally.click` 的 docs 更新

### 4.4 用戶記憶
- [ ] 4.4.1 `~/.claude/projects/.../memory/MEMORY.md` 加 arcrun MCP entry
  - URL: `https://mcp.arcrun.dev/mcp/mcp`
  - tool 前綴: `arcrun_*`
  - finally.click 過渡期到何時
- [ ] 4.4.2 polaris/mira/CLAUDE.md 提到 daemon / arcrun / MCP 的部分對齊新命名

### 4.5 過渡期（舊 endpoint 不立刻砍）
- [ ] 4.5.1 舊 `mcp.finally.click/mcp/mcp` 加回應 header `Deprecation: true` + `Link: <https://mcp.arcrun.dev/mcp/mcp>; rel="successor-version"`
- [ ] 4.5.2 舊 worker 繼續服務 30 天（2026-06-07 為止）
- [ ] 4.5.3 廢止排程：2026-06-07 後舊 worker 改回 410 Gone + 提示換新 URL

### 4.6 驗證
- [ ] 4.6.1 `mcp.arcrun.dev/mcp/mcp` initialize + tools/list + 一個 tool call 全通
- [ ] 4.6.2 我的 Claude Code config 切到新 URL，用 `mcp__arcrun__search_components` 端對端測
- [ ] 4.6.3 grep `u6u` 在 `matrix/arcrun-mcp/` 結果為 0（除了 changelog 紀錄）

---

## 風險追蹤

- 風險 1：backfill 跑進去發現某些 contract.yaml 格式跟 registry 期望不一樣 → 緩解：dry-run 先看，必要時補 contract 欄位
- 風險 2：Phase 4 rebrand 期間用戶 client 設定亂 → 緩解：過渡期 + Deprecation header
- 風險 3：自動註冊 hook 失敗導致部署被擋 → 緩解：degraded mode（warning 不 fail）

---

## Known Issues（吃狗糧發現的，先記錄）

### KI-1：u6u-mcp README URL 寫錯
- README 寫 `mcp.finally.click/mcp`，實際是 `mcp.finally.click/mcp/mcp`（basePath + route）
- 影響：用戶照 README 裝完試打不通
- 解法：rebrand 時順便修

### KI-2：inkstone-component-registry 跟 arcrun-registry 並存
- 兩個 worker 都活著，u6u-mcp 之前指錯
- inkstone-component-registry 是舊版（2026-03-24）、arcrun-registry 是現役（2026-04-16）
- 解法：Phase 1 backfill 完成後，inkstone-component-registry worker 廢止

### KI-3：search 對自然語言不夠靈敏（吃狗糧第一個發現）
- 現象：
  - `search("從 KBDB 讀取或查詢 block")` → 0 結果
  - `search("kbdb")` → 3 結果（kbdb_ingest / kbdb_patch_block / kbdb_create_block）
- 根因：搜尋走 embedding（bge-m3）相似度，但既有零件清單少（30 個）+ description 寫得正式，自然語言整句的 embedding 跟 description 距離太遠
- 影響：**致命** — AI 第一句永遠是自然語言整句，回 0 就會放棄 search 改寫 Python
- 解法（Phase 3 處理）：
  1. embedding search 之外加 keyword fallback（split query → 對 canonical_id / display_name / tags 做 ILIKE）
  2. 或 lower threshold（目前 SCORE_THRESHOLD = 0.5，可能過高）
  3. MCP get_component_guide 教 AI 「找不到時拆關鍵字再 search」
- 優先級：P1（會擋推廣）
