# G3 · 结论层状态写入 · 实施设计（2026-09-18）

> **状态**：设计定稿，待实施。
> **权威依据**：`MEMORY-GOVERNANCE-20260917.md` §8（用户 2026-09-18 拍板）+ `BATTLE-PLAN-20260917.md` §M2 并入项。
> **纪律来源**：契约 §6 尾注（lint 只报告不自动改）+ S10.4（不建状态源）+ 语义引擎铁律。

---

## 1. 一句话

**M2 说「这条可能过时」，G3 在下次写入时决定要不要标。**
M2（lint）已完工：只读、只报告、43/43 套件、全量回归 119/0。
G3 是**写入侧**：`memory_note_pre` 写新结论时，比对同主题旧条目，把被取代的那条标 `superseded`。

## 2. 触发范围（用户裁定，不可扩大）

| 路径 | 是否触发 G3 | 理由 |
|---|---|---|
| `memory_note_pre` · `kind='note'` | ✅ **唯一触发点** | 笔记 = 结论，append 是**错误**语义，才是矛盾滋生地 |
| `memory_note_pre` · `kind='plan'/'handoff'` | ❌ 不触发 | 白板/账本是**视图**，其状态归卡片，不归本机制 |
| `memory_log_pre` | ❌ **零改动** | 日志 = 流水，append 是**正确**语义 |

## 3. 三条硬约束（违反即回滚）

### 3.1 ★ 语义引擎铁律：必须 fail-soft 退回词法臂
```
语义引擎可用 ⇒ 语义臂检索同主题
语义引擎不可用 ⇒ 退回词法臂，**行为正常，不报错、不跳过写入**
```
**绝不允许**：一个引擎的存在成为另一个生效的前提；任一引擎不可用导致状态不写或写入失败。

### 3.2 ★ 保守阈值：宁可漏判，不可误判
- 误判代价**不对称**：漏判 = 矛盾继续存在（回到现状，可接受）；**误判 = 有效结论被标作废，比不改更糟**。
- ⇒ **只在高置信度时自动标**；其余**只报告不标**（与 M2 lint 的分工呼应）。

### 3.3 ★ 不新建状态源（S10.4）
`status` 是**已有字段**（`l0-extract-pre.js:56` `L0_STATUSES`），G3 只是让它**第一次被写入**。
**禁止**：另建状态表 / 新配置文件 / 平行账本。

## 4. 撤销通道（U1，必需项）

**用户明确要求**（原话：「标错成 superseded 后，要有个撤销通道？」）。

**方案 U1**：`memory_note_pre` 增参数 `restore: [mem_id...]`
- 语义：把指定 id 的状态改回 `current`
- **必须留痕**：谁在何时把它改回（否则又变成「静默改写」—— 正是 §1 标本的成因）
- U2（面板可点）留给 S 层；U3（追加变更记录）与 §3.1「status 是字段不是新状态源」冲突，不采用

## 5. 实施边界（本轮做什么 / 不做什么）

| 项 | 本轮 |
|---|---|
| 判定函数（纯函数、可单测） | ✅ 做 |
| 词法臂（零依赖，保底） | ✅ 做 |
| 语义臂（复用现有 recall） | ✅ 做，**但必须可降级** |
| 实际写 `status` 到笔记文件 | ⚠️ **谨慎**：只改**本插件自己管理的** MEMORY.md 块，且经正常写入通道 |
| 变更留痕（写入位置） | ✅ 做（复用现有日志通道，不新建文件） |
| 面板展示 status | ❌ 不做（属 S 层） |
| `memory_log_pre` 任何改动 | ❌ **零改动**（套件断言） |

## 6. 验收口径（能失败）

- [ ] 写新结论、显式声明取代旧条目 ⇒ 旧条目 `status` 变 `superseded`
- [ ] **误标可撤销**：走 U1 改回 `current`，**且有留痕**
- [ ] **语义引擎不可用时**：退回词法臂，行为正常，**不报错、不跳过写入**
- [ ] `memory_log_pre` 路径**零改动**（断言：日志写入不触发任何 status 写入）
- [ ] 每条都在 `tests/smoke/` 有套件，且**故意改坏实现时会红**

---

## 7. 待用户确认的两个判据（唯一阻塞点）

按契约 §8.5「阈值要保守」，以下两点**必须用户拍板**，我不自行决定：

1. **自动标的置信门槛**：
   - (a) **只认显式声明**（新结论正文里写明「取代/替换/作废」+ 指向旧条目）⇒ 零误判可能，但覆盖窄
   - (b) 显式声明 **+** 高相似度（词法/语义臂都命中同一旧条目）⇒ 覆盖率好，但有误判风险
   - 建议 **(a) 起步**，(b) 后续按实测数据再开

2. **`superseded` 的可见后果**：
   - 现状：非 `current` 条目在**检索侧被过滤**（`index.js:5834` 契约 I5）+ 注入侧另有一道
   - ⇒ 标错 = 该结论**立刻搜不到**。确认这是期望行为，还是希望「降权」而非「剔除」？
