---
tags: [零件架構, 薄殼, 平台原則, 機制說明, 踩坑]
gloss: 退役/降級零件要同步清「AI 搜尋零件的三個源」（示例 yaml + parts.ts 硬編碼清單 + offline validate），只改一處會留殘留誤導下個 CC；沒對應 recipe 時誠實留 TODO 不硬塞語意不符的 canonical_id。
---
# 零件退役要清「AI 搜尋零件的三個源」

← [[decisions/00-INDEX]]

**來源**：issue #13（telegram/gmail/sheets/line 從內建零件降級走 recipe、刪 ai_transform_compile/run）
**commit**：caa8e10（步驟1 示例 yaml）、764f657（步驟2 parts.ts）
**最後更新**：2026-06-28

## 摘要
退役或降級一個零件（改成走 recipe、或直接刪）時，**AI/操盤手「能找到這零件」的來源不只一個**。
只改一處就宣布退役 → 別處殘留會讓下個 CC 或 Haiku 誤判「這零件還在、還能用」（死代碼/殘留＝錯誤環境信號）。
退役 SOP ＝同步清「AI 搜尋零件的三個源」，外加：沒對應 recipe 時誠實留 TODO，別硬塞語意不符的 canonical_id（假綠）。

## 重點
- **三個源（退役必查）**：
  1. **示例 yaml**——workflow 範例裡的 `component: telegram` 之類。退役時改成 recipe canonical_id（`telegram_send`）。
  2. **`cli/src/commands/parts.ts` 硬編碼清單**——手寫的「有哪些零件」常駐清單，**必然 stale**，是退役最易漏的源。
     步驟2 已把 telegram/gmail/sheets/line 改 recipe canonical_id、移除已刪的 ai_transform_compile/run。
  3. **offline validate**——**這個是設計不是殘留**：offline validate 刻意不連網、跳過遠端查零件，
     所以它「不檢查零件存不存在」是 by design。第三個污染源留 issue，**不當 bug 修**。
- **gmail 讀取假綠（已避）**：gmail 的**讀取**（`fetch_unread` / `action: list`）**沒有對應 recipe**，
  硬指成 `gmail_send`（寄信 recipe）＝語意不符的假綠。正解＝**留 TODO 待 seed 補 `gmail_list`**，不硬塞。
  「有個 canonical_id 可填」≠「這個 id 對」。
- **parts.ts 必 stale**：它是手寫常駐清單，不是從 registry 動態生成 → 任何零件增刪它都不會自動跟上，
  退役 SOP 要把它列成「固定必清項」。
- **退役 ≠ 宣告**：清殘留是實際動作（改/刪所有源），不是「改完一處說一聲完成」。

## 實體
- **AI 搜尋零件的三個源**（示例 yaml / parts.ts / offline validate）— 操盤手判斷「零件存不存在」的依據來源；退役要逐源處理。
- **parts.ts 硬編碼清單**（cli/src/commands/parts.ts）— 手寫常駐零件清單，必 stale，退役固定必清項。
- **offline validate 跳過零件查**（by design）— 不連網驗證刻意不查零件存在性；是設計不是殘留，留 issue。
- **硬塞 canonical_id 假綠**（gmail 讀取→gmail_send）— 沒對應 recipe 時填語意不符的 id 充數，違 mindset §7。

## 關聯
### 內文知識關係
- 零件退役 >> 必須清 >> AI 搜尋零件的三個源
- parts.ts 硬編碼清單 >> 必然 >> stale
- offline validate 跳過零件查 >> 屬於 >> 設計（非殘留）
- 硬塞 canonical_id >> 是 >> 假綠
- 沒對應 recipe >> 正解是 >> 留 TODO 補 seed
### 卡片關係
- [[零件退役要清三源]] >> 落實 >> [[工作流是default零件是例外]]
- [[零件退役要清三源]] >> 同類於 >> [[薄殼規則晚於實作-MCP漂移是歷史債]]（都是「常駐清單/規則晚於實作 → 漂移殘留」）
