# 03 — 記憶層：跨對話、跨專案的記憶

上一層：[02 規則層](02-rules-file.md)　下一層：[04 任務層](04-task-files.md)　模板：[templates/MEMORY.md](templates/MEMORY.md)

---

## 記憶層跟規則層的分界

| | 規則層（`CLAUDE.md`） | 記憶層（`memory/`） |
|---|---|---|
| 跟著誰走 | **repo** | **人** |
| 換一台機器 | 還在（在版控裡） | 要搬 |
| 換一個專案 | 不適用 | **還適用** |
| 新來的協作者看得到 | ✅ | ❌ |
| 載入方式 | 每次全文 | 索引常駐、內容按需撈 |

**判準：如果一個新來的人加入這個 repo 也需要知道，它屬於規則層。
如果只有「我」需要（或只有「我跟這個 AI」需要），它屬於記憶層。**

實例：
- 「這個 repo 的 commit 前要跑哪幾支守衛」→ 規則層。
- 「我習慣先要計畫再要 code，因為我在計畫階段改比較便宜」→ 記憶層。

---

## 五個分類

前四類是常見的 agent 記憶分類（`type` 欄位），第五類是**這套系統自己加的，也是最有價值的**。

| type | 存什麼 | 例子 |
|---|---|---|
| `user` | 我是誰：角色、專長、偏好 | 「回覆一律中文；英文 UI 字樣要附中文意思」 |
| `feedback` | 我給過的工作方式指導（含糾正與確認過的做法） | 「設計階段不以省事為推薦判準 —— 某次當場被糾正」 |
| `project` | 進行中的目標與限制，**不是從 code 或 git 看得出來的那些** | 「這一版的唯一焦點是上架，任何提案一律往收斂推」 |
| `reference` | 外部資源指標（URL、儀表板、票號） | — |
| **`obsolete`** | **被否決／被取代的決策** | 見下 ↓ |

每一則**一個檔案、一件事**，前面掛 frontmatter：

```markdown
---
name: plan-before-code
description: 大改動一律先出計畫與估時，不直接寫 code
metadata:
  type: feedback
---

大改動先出【計畫＋估時】讓我裁示，不要直接產出 code。

**Why:** 計畫階段的錯誤改一行字，實作階段的錯誤改三個檔案。
**How to apply:** 收到「做 X」時，先回一份「要動哪些檔／風險／估時」，等我說「開始」再動手。

相關：[[green-light-needs-numbers]]、[[obsolete-log]]
```

`[[name]]` 是相互連結。**連到一則還不存在的記憶也沒關係** —— 那標示的是一件之後值得寫的事，不是錯誤。

---

## 🚨 作廢紀錄：整套系統裡最被低估的一個檔

大部分人的記憶只存「拍板了什麼」。**這套系統同時存「否決了什麼、為什麼」。**

它解決一個非常具體、而且一定會發生的問題：

> 三週後，AI（或你自己）會再提一次同一個已經被否決的方案。
> 而且它會提得很有說服力，因為當初否決的理由**不在任何檔案裡**。

於是你要嘛重新討論一次（浪費），要嘛不小心採用了（更糟）。

**做法**：每次否決一個方案，就在作廢紀錄裡壓縮成 1–3 行：

```markdown
## B 區：被推翻／否決的決策

- **把整包原始碼公開**（<日期>定案：不公開）
  理由：讀者實際會消費的是「能跑的東西 ＞ 講得清楚的一個決策 ＞ README ＞ 真的去讀原始碼」，
  公開的邊際效益小，代價是把後端結構與內部機制一次交出去。
  ⇒ 前置作業已寫進操作手冊，**哪天真要公開才照著跑**，不要因為看到它就排進行程。

- **註冊時多問一個「你從哪裡知道我們的」欄位**（<日期>取消）
  理由：加一個欄位換一個沒人會看的統計，而且它會拖慢起手流程。
  ⚠️ 這個方案聽起來很划算，所以**每隔幾週就會有人重提一次** —— 包括我自己。
```

然後在規則檔或記憶索引裡加一條**硬規則**：

> **提新方案、或覺得「這個好像可以做」之前，先讀作廢紀錄。**

### 為什麼這一格特別值錢

- 對協作：它**防重議**，直接省下重複討論的時間。
- 對你自己：**「我否決過什麼、為什麼」比「我做了什麼」更能證明判斷力。**
  做過的事只證明你動過手；否決紀錄證明你在同一批資訊下做過取捨，而且說得出理由。

---

## 三條容易踩的坑

### ① 記憶是「寫的時候是真的」，不是「現在是真的」

記憶沒有過期機制。一則三週前寫的記憶如果提到某個檔案、函式或旗標，
**用之前要先確認它還在**。

⇒ 判準：**記憶裡的「事實」要當作線索，不是當作結論。**

### ② 硬數字不要存進記憶

「有 84 張表」這種數字存進記憶的那一刻就開始腐爛，而且腐爛得**完全沒有症狀**。

⇒ 正確做法：記憶裡存**「怎麼取得現值」**，不存值本身：

```markdown
硬數字（表數／端點數／migration 數）一律不存記憶，
用 `backend/.venv/Scripts/python.exe tools/spec_check.py --list` 現算。
```

### ③ 不要存 repo 已經記錄的東西

code 結構、過去的修正、git 歷史、規則檔已經寫了的 —— 這些都不該進記憶，
因為它們有更好、更不會漂移的家。

**如果有人要求你記住其中一件，正確的反應是問：「這件事哪裡不明顯？」** ——
不明顯的那一層才是值得存的東西。

例：「記住我們用 PostgreSQL」❌（`docker-compose.yml` 就寫著）
→「記住本機是 SQLite、雲端是 PostgreSQL，**而且兩者的差異咬過我們四次**」✅

---

## 索引檔怎麼寫

`MEMORY.md` 是唯一會**每次載入**的記憶檔，所以它跟規則檔受同一條成本約束：
**一則一行，只放指標與鉤子，永遠不放內容。**

```markdown
- [01 我是誰與合作方式](01-user-and-collab.md) — 回覆語言、要計畫不要 code、範圍延伸先報價
- [02 專案定位](02-career-and-work.md) — 唯一焦點與收斂原則；硬數字一律現算
- [03 排程與硬錨點](03-launch-and-brand.md) — 權威主表在哪、哪些日期不能動
- [04 已拍板的產品決策](04-product-decisions.md) — 別再提替代方案的那些
- [05 作廢紀錄](05-obsolete-log.md) — **提新方案前先讀**，防重議
```

那個專案的實際比例：索引 5 行，內容 756 行。**索引只佔 0.7%，但它決定了另外 99.3% 會不會被撈出來。**

---

## 什麼時候寫記憶

| 時機 | 寫成什麼 |
|---|---|
| 我糾正了 AI 的做法 | `feedback` —— **含「為什麼」**，否則下次它只會照做不會推廣 |
| 我拍板一個不可逆的決定 | `project` ＋ 決策紀錄各一份（用途不同：一個給 AI，一個給未來的我） |
| 我否決一個方案 | **`obsolete`**（最重要的一類，理由一定要寫） |
| 一個做法被驗證有效 | `feedback` —— 確認過的做法跟糾正一樣值得存 |

⚠️ **不要在對話結束時「整理一波」** —— 那時候你已經忘了為什麼。當下就寫，一則一件事。

---

## 接下來

- 任務層六個檔 → [04-task-files.md](04-task-files.md)
- 記憶檔模板 → [templates/MEMORY.md](templates/MEMORY.md)、[templates/memory-entry.md](templates/memory-entry.md)
