# 一個人 × AI：一套會自己擋下錯誤的專案管理系統

> **一句話**：分工不是「AI 寫、我看」，是**它產出、我設閘門**。
> 而閘門的正確歸宿不是文件裡的一條規則 —— 是一支**會擋下來的機器檢查**。

這是一套在**真實單人專案上跑了數個月**的 AI 協作工作流程，不是理論。
它長成現在這樣，每一格都是某次「我沒做到」之後補上的。

拿走它需要的東西：一個 AI coding agent（Claude Code、Cursor、Copilot Workspace 都適用，
本文以 Claude Code 的 hook 機制為例）、一個 git repo、一個純文字編輯器。**不需要任何服務或訂閱。**

---

## 它在解決什麼問題

AI 讓「產出速度」不再是瓶頸。瓶頸整個移到一個新位置：

> **我怎麼知道它是對的？**

而且失敗的形狀變了。AI 寫出來的 code 很少會「一眼看出是錯的」——
它通常**畫面全對、console 乾淨、測試全綠**，然後在某個你沒看的角落安靜地壞掉。

這套系統守的就是**安靜的錯誤**。它由兩個部分組成：

| 部分 | 回答的問題 | 在哪 |
|---|---|---|
| **三層記憶** | AI 每次開新對話都失憶 —— 它怎麼知道這個專案的規矩？ | [02](02-rules-file.md)・[03](03-memory.md)・[04](04-task-files.md) |
| **四層防線** | 它產出之後，誰來證明那是對的？ | [05](05-guards.md) |

---

## 三個核心概念

### ① 每一句話都要先回答「它在回答哪個問題」

寫錯地方的代價不是亂，是**兩份日後一定會漂移**，而且沒有人會發現。

所以每一個檔案被指定**只回答一個問題**：

```
接下來做什麼、還要花多少時間  →  排程表
那天發生什麼、當下為什麼那樣選  →  日誌（append-only）
做完了嗎、怎麼證明              →  證據帳本（每列都要有實測數字）
點哪顆按鈕、手把手怎麼做        →  操作手冊（消耗品）
系統現在長什麼樣                →  規格
事故的來龍去脈與教訓            →  事故記錄
被否決／被取代的決策            →  作廢紀錄（提新方案前先查，防重議）
```

新資訊沒有家的時候，正確動作**不是開新檔**，是回答上面那句話。

### ② 四層成本結構 —— 貴的是規則正文，不是守衛

這是整套系統唯一真正反直覺的地方。直覺會說「規則寫清楚一點就好了」，但是：

| 層 | 誰執行 | 每次對話的成本 | 忘得掉嗎 | 所以它該放什麼 |
|---|---|---|---|---|
| **hook** | 執行環境 | **0**（不觸發等於不存在） | **不會** | 指令樣式、檔案事件、時間 |
| **守衛腳本** | 我，提交前 | **1 行**（原始碼永不進上下文） | 會忘記跑 ⇒ 再往下推一層 | 「做完了也不會知道出錯」的事 |
| **規則正文** | AI，每次對話被動載入 | **它的行數 × 每一次對話** | **非常容易** | 只有機器接不住、必須靠判斷的 |
| **事故記錄** | 需要時才讀 | 0 | — | 症狀、結構性根因、現在誰接住它 |

> **一條規則的正文長度是它的成本，不是它的重要程度。**

可指認的反證：某條規則白紙黑字寫在規則檔裡，還是**連續發作三次**。
三次都不是不知道規則 —— **自動載入 ≠ 自動遵守**。一條規則躺在 700 行裡，注意力份額趨近於零。

⇒ 所以規則的正確歸宿是**往下推一層**：能變 hook 的變 hook，能變守衛的變守衛。
在那個專案裡，規則正文從 555 行降到 341 行，**降下來的那 214 行不是被刪掉，是被推去 hook 和守衛了**。

### ③ 教訓迴圈 —— 把一次痛變成永久的攔截

事故的第一句不可以是「我下次會小心」。**那句話不可證偽，所以它擋不住第二次。**

```
踩到 ──► 問「結構原因是什麼」
       │
       ├─ 指令樣式／檔案事件／時間 ─────► 加一條 hook（＋正反向演練）
       ├─ 「做完了也不會知道出錯」 ─────► 加一支守衛（＋故障演練）
       └─ 只能靠判斷 ──────────────────► 才留在規則正文裡（最貴，所以最後才考慮）
```

**同一型錯誤只會花你一次。**

---

## 目錄

| 檔案 | 內容 |
|---|---|
| **[index.html](index.html)** | **一頁看完**：架構圖 ＋ 這 29 個檔的地圖 ＋ 上手路徑。瀏覽器直接開，無需任何工具 |
| [01-overview.md](01-overview.md) | **全貌**：三層記憶 × 四層防線怎麼咬合，一張圖 |
| [02-rules-file.md](02-rules-file.md) | **規則層**：規則檔怎麼寫、什麼該進什麼不該進、怎麼瘦身 |
| [03-memory.md](03-memory.md) | **記憶層**：跨對話記憶的五分類，與為什麼一定要有「作廢紀錄」 |
| [04-task-files.md](04-task-files.md) | **任務層**：六個檔各答一個問題，與「交付當下就登記」 |
| [05-guards.md](05-guards.md) | **四層防線**：hook／守衛／演練／端到端，含「綠燈可信度」判準 |
| [06-daily-loop.md](06-daily-loop.md) | **日常循環**：一次完整的工作流程，從一句需求到交付登記 |
| [07-adopt.md](07-adopt.md) | **怎麼採用**：第 1 天 30 分鐘、第 1 週、第 1 個月 |
| [templates/](templates/) | **可直接複製**：規則檔、記憶檔、任務檔、hook、守衛、演練、skill |
| [prompts/](prompts/) | **可直接貼**：六段把上面這些規矩變成實際指令的 prompt |
| [bat/](bat/) | **Windows 操作入口範本**：把日常開發、提交前驗收、首次使用、後端工具、發布與權限管理收斂到同一個專案 CLI |

**只有 30 分鐘的話**：開 [index.html](index.html) 看那張架構圖 → 讀本檔〈三個核心概念〉→ 跳到 [07-adopt.md](07-adopt.md) 的「第 1 天」。

---

## 這套東西真的在跑嗎

它長出來的那個專案的規模（單人開發，數字由守衛現算而非估計）：

```
103 張資料表 · 70 支 migration · 346 支 API 端點 · 115 個擴充點
64 支端到端測試 · 17 篇事故記錄 · 62 條決策紀錄 · 0 支 unit test
```

而它每天運作的樣子長這樣 —— 寫這份文件的當下就發生一次，
我想拿一個數字、指令接了 `| tail`，**第一層 hook 在指令送出去之前就擋下來**：

```
[hook: pipe-to-head-tail]
守衛指令接了 | head/tail —— 你看到的 exit code 會是 head/tail 的，不是守衛的。
曾真的因此帶著紅燈提交過。
改法：`cmd > out.txt 2>&1; code=$?` 再讀檔，或 `set -o pipefail`。
```

注意兩件事：

1. **它不是提醒我小心，是在指令送出去之前就不讓它跑。**
2. **訊息本身帶著它的來歷** —— 下一個看到它的人（包括兩週後的我）不需要問「為什麼有這條規則」。

---

## 誠實邊界

先講，比被發現好。這四條是這套系統**做不到**的事：

- **它守的是安靜的錯誤，守不住「需求本身就錯」。** 那一層目前沒有任何機器接得住，
  單人專案也沒有第二個人 review。這是真實的缺口，不是還沒做完的功能。
- **那個專案沒有 unit test（0 支）**，測試全部是端到端 ＋ 守衛 ＋ 演練。
  取捨是刻意的（單人、前端無 build step、真正咬人的是環境差異不是純函式），
  但**代價是回歸定位慢**：紅了要自己二分找是哪一層。這一題不打算美化。
- **hook 的設定檔通常不進版控**（多數 agent 的設定目錄都被 gitignore 擋掉）⇒ 換機器要重接一次。
  所以**安裝動作本身要寫成版控裡的腳本**，讓它是「再跑一次」而不是「重寫一遍」。
- **誤報比漏報更危險。** 誤報會讓人乾脆把守衛關掉，然後你連漏報都不會知道。
  所以每加一條規則都必須附**反向案例** —— 否則一支「全部擋掉」的守衛也會拿滿分。

---

## 授權

隨意取用、修改、商用。不需要署名。
如果某一條規則救了你一次，那它就完成任務了。
