# Memory Bank 高级规则

> 此文件包含索引规范、冲突处理、阈值规则、预算控制等详细规则。

---

## 路由规则规范

### 字段定义

| 字段 | 类型 | 说明 |
|------|------|------|
| `path` | string | 相对于 memory-bank/ 的文件路径（唯一键） |
| `title` | string | 文件第一个 # 标题 |
| `summary` | string | 2-4 句话摘要，强调"何时该读它" |
| `updated` | date | ISO 8601 日期格式：YYYY-MM-DD |

### 子目录索引额外字段

| 字段 | 适用于 | 说明 |
|------|--------|------|
| `status` | requirements | Proposed / Accepted / Implementing / Done / Deprecated |
| `type` | learnings | bug / performance / integration |

### 格式示例

```markdown
| path | title | summary | updated |
|------|-------|---------|---------|
| details/tech.md | Tech Stack | 电商后台，技术约束见此文件 | 2024-01-20 |
```

---

## 路由逃生门（自愈机制）

### 问题场景
- MEMORY.md 丢失或损坏
- 新文件未被收录到路由表
- 用户明确要求读取某个路径

### 逃生规则

**场景 1：入口缺失**
```
检测到 MEMORY.md 不存在或为空
→ 扫描 memory-bank/ 下所有 .md 文件
→ 自动重建 MEMORY.md
→ 提示用户"入口文件已重建，请检查"
```

**场景 2：用户明确指定路径**
```
用户说"读取 memory-bank/details/xxx.md"
→ 允许读取（即使不在路由表中）
→ 读取后自动添加到对应的 index.md 或 MEMORY.md
→ 提示用户"已添加到路由表"
```

**场景 3：Bootstrap 时的固定 Allowlist**
```
Bootstrap 扫描时允许读取（不依赖索引）：
- README.md
- package.json / go.mod / Cargo.toml / pyproject.toml
- 目录树（前两层）
```

---

## 机器区块冲突处理

### 冲突检测机制

机器区块可选包含元信息（建议）：
```markdown
<!-- MACHINE_BLOCK_START -->
<!-- blockVersion: 3 | lastUpdated: 2024-01-22T10:30:00Z -->
```

**检测流程**：
1. 若存在元信息，读取机器区块的 `blockVersion` 和 `lastUpdated`
2. 计算当前机器区块内容的 hash
3. 与上次写入时保存的 hash 对比
4. 如果 hash 不同 → 检测到用户修改

### 冲突处理策略

**发现冲突时**：
```
检测到 MEMORY.md 机器区块被手动修改：
- 上次更新: 2024-01-22T10:30:00Z
- 当前内容与预期不符

选择处理方式：
1. 保留你的修改，跳过本次更新
2. 用 AI 更新覆盖你的修改
3. 合并：AI 更新追加到你的修改后面

请选择 (1/2/3):
```

**不产生冲突副本**：避免文件污染，让用户明确选择。

---

## 触发阈值硬规则

### Decision（技术决策）必须满足

写入 details/patterns.md 的决策必须包含：
- ✅ **决策内容**：选了什么
- ✅ **原因**：为什么选它
- ✅ **取舍**：放弃了什么选项
- ✅ **适用范围**：什么场景用
- ❌ **不适用**：什么场景不用（可选）

**格式示例**：
```markdown
| 日期 | 决策 | 原因 | 取舍 | 适用范围 |
|------|------|------|------|----------|
| 2024-01-22 | 错误处理用 pkg/errors | 支持 wrap + stack trace | 放弃标准 errors | 所有业务逻辑层 |
```

### Learning（经验教训）必须包含

写入 details/learnings/ 的经验必须包含：
- ✅ **症状**：如何发现问题
- ✅ **根因**：根本原因是什么
- ✅ **解决方案**：怎么修的
- ✅ **预防措施**：如何避免再次发生（断言/监控/测试）

**不合格示例**（拒绝写入）：
```
问题：支付超时
解决：改了超时时间
```

**合格示例**：
```
问题：支付超时
症状：高峰期支付成功率下降到 60%
根因：默认超时 3s，支付宝网关响应 P99 = 4.2s
解决：超时改为 10s + 增加重试 2 次
预防：添加支付耗时监控告警，P99 > 5s 时报警
```

---

## 归档阈值规则

当 `MEMORY.md` 中的 `Current Focus` 满足以下任一条件时，触发归档：

- 已完成条目超过 20 条（`- [x]` 数量）

归档行为：

- 移入 `details/archive/*.md`
- `MEMORY.md` 仅保留当前焦点、下一步、阻塞项

---

## 预算控制详细规则

### 行数计算方式
- 机器区块和用户区块都计入
- 空行计入

### 预算分配

> **注意**：以下是 Plugin 注入和 memory-reader 的预算。Direct-first 读取（主 Agent 直接 read）使用不同阈值，见下方说明。

| 类型 | 预算 |
|------|------|
| 固定加载 (MEMORY.md) | 12,000 字符（超出从头截断） |
| memory-reader 每次调用 | 最多 10 个文件 |
| 额外加载总行数 | 最多 500 行 |

### Direct-First 阈值（v7.1）

| 条件 | 行为 |
|------|------|
| 目标文件 ≤ 3 个 | 主 Agent 直接 `read`，无需 memory-reader |
| 预估行数 ≤ 300 行 | 主 Agent 直接 `read`，无需 memory-reader |
| 超过上述阈值 | 升级到 memory-reader |

> 这两套阈值服务不同场景：Direct-First 用于主 Agent 快速读取小量文件，memory-reader 用于大批量/复杂读取。

### 超预算降级策略

当候选文件总 size 超过 500 行时：
```
1. 固定加载 MEMORY.md（不计入预算）
2. 按相关性排序候选文件
3. 按 size 从小到大依次加载
4. 累计 size 达到 500 行时停止
5. 未加载的文件提示用户："以下文件相关但未加载（预算限制）：..."
```

### 大文件处理
- 如果单个文件 > 200 行
- 只读取前 100 行 + 最后 50 行
- 中间插入 `[... 省略 {n} 行 ...]`

---

## 扩展点

| 情况 | 动作 |
|------|------|
| 需求 > 20 个 | 索引自动分页 或 添加 status 筛选 |
| learnings > 30 条 | 按 type 分子索引 |
| 多人协作 | 添加 author 字段到索引 |
| 大仓库 | bootstrap 扫描增加更多预算限制 |
