# 作废标记语义修正 + Procedural Memory + 长期记忆审批（2026-09-18 设计稿）

> **用户裁定**（本节其余内容均由此推出）：
> ① 「**这个 reacted 不是过滤掉**……**并不是挡，我感觉是备注**」；
> ② 「如果遇到这个，后面应该说明现在**更正的内容在哪个哈希值里面**，方便 AI 去搜索」；
> ③ 「这个**长期记忆审批**的问题……用户都说看不懂……**太抽象了**，名字也不知道，流程是啥也不知道，没法审，**只能盲确认**」；
> ④ 「这个教训和这个**攻关完成的项目**，和**多次重复的事件**，应该都可以上升为 **skill 式**的。这个长期记忆就是 **procedural memory**，你看能不能和那个做结合」。

---

## 1. ★ I5 再修正：从「按状态分流」改为「一律返回、一律标记」

### 1.1 我上一版的错误

我上轮提的方案是「`superseded` 放行 + 标记，`retracted` **继续硬过滤**」。
**用户否掉了，而且理由比我的更根本**：

> 「如果你不记住这个教训的话，你还会再踩。所以**并不是挡，我感觉是备注**。」

我的分法来自**检索视角**（过时的信息不该干扰当前判断）；用户的分法来自**学习视角**
（**做错的事恰恰是最该被记住的**）。对记忆系统而言，后者才是目的——
`retracted` 不是"垃圾数据"，它是**一条教训**：*「这条曾经被当成结论写下来，后来发现是错的」*。
把它藏起来，等于**系统性遗忘自己的错误**，这正是用户说的"还会再踩"。

### 1.2 修正后的语义（三态一律返回）

| status | 语义 | 呈现 |
|---|---|---|
| `current` | 现行结论 | 原样（**逐字节向后兼容**） |
| `superseded` | 被更新的结论取代 | `⚠已作废（已被 mem_<hash> 取代）` |
| `retracted` | 判断有误 / 主动撤回 | `⚠已撤回（原因：<reason>；更正见 mem_<hash>）` |

**关键变化**：`isRetrievablePre` 不再过滤任何 status（只对**未知值 fail-closed**，防未来新增枚举时静默放行）。

### 1.3 「指向哈希值」= 让 AI 能自己去追（用户 ②）

用户要求「说明更正的内容在哪个哈希值里面，方便 AI 去搜索」——
这要求标记里带上**可检索的 id**，而不只是一句"已作废"。落地要点：

- id 就是既有的 `mem_<32hex>` 锚点 id（**已有的东西，不新建 ID 体系**，守 S10.4）
- 标记形态：`⚠已作废（已被 mem_xxxx 取代）` ⇒ AI 可直接拿这个 id 去 `memory_recall_pre` / `grep`
- `retracted` 额外带 **reason**（为什么撤回）——这才是"教训"的正文，比 status 本身有价值

> ⚠️ **安全纪律（已在 R4-A 探针锁定）**：id 只认 `/^mem_[0-9a-f]{32}$/` 形态，
> 不合法一律丢弃 —— 防止把任意文本拼进检索呈现。

### 1.4 对 I5 的最终影响

原 I5：「非 `current` 的条目在**检索结果与注入内容两处**都被过滤」。
**新语义**：**检索侧完全不过滤**（一律返回 + 标记）；**注入侧维持过滤**——
理由是注入是**常驻目录**（B0 仅 800 token），拿常驻预算装过时条目会挤掉现行结论；
检索是**按需**的，AI 主动问什么才给什么，装一条带警告的过时结论划算。

⇒ 即 **I5 的"两处"要求被拆开**：检索侧从"过滤"改为"标注"，注入侧不变。

---

## 2. ★ 仓库里已经有 procedural memory（用户的 ④ 不是新建，是接线）

**这是本次最重要的发现**：用户说"看能不能和那个做结合"——**那些东西已经存在了**：

| 已有资产 | 位置 | 作用 |
|---|---|---|
| `createProcedureStorePre` | `lib/procedure-store-pre.js` | 技能店：`observe/promote/activeProcedures/renderChecklist/touch/addEvidence` |
| `createMemoryHubPre` | `lib/memory-hub-pre.js` | 三层编排器（episodic / **fact** / **procedure**） |
| `isObservationOnlyPre` | `lib/procedure-observation-pre.js` | 观察型候选（不可晋升）标记 |
| `act.skill` 段 | `lib/activation-inbox-pre.js` | **技能注入进投递面**（`renderSkillBlock` 渲染 checklist） |
| 技能召回 | `lib/context-host-pre.js:524+` | query 匹配 active skill → 相似场景自动附上 |
| 三层记忆面板 | `lib/client.js:2552+` | 「记忆中枢」页：晋升/激活/弃用/置顶 |
| 证据制晋升闸门 | `index.js:522-531` | `minSessions=3` / `minSuccess=2` / `correctionCap=0.3` / 高风险需批准 |

**⇒ 用户想要的「教训 / 攻关完成的项目 / 多次重复的事件 → skill 式」，机制上就是 `procedure` 层。**
不需要新建系统，需要的是：**接通 + 让它好用 + 让它能被审**。

> ⚠️ **agent 曾在此处判断错误（已更正）**：初稿写「`procedurePromotionEnabled=false` 与宣传不一致」，
> 把它当成默认值 bug。**实际是有意关闭**（Hermes 遗留未修）——见 §2.1。


### 2.1 出厂为什么是**关的**（用户裁定 2026-09-18，**纠正 agent 的误判**）

`index.js:513  procedurePromotionEnabled: false`

**agent 原判断（错）**：写成"宣传与实现不一致"，当成默认值 bug。
**用户裁定**：

> 「记忆晋升是因为**之前的记忆系统有这个问题**，它用的是 **Hermes 那套**。
> 你可以从记忆里看到我要改，**所以才先关掉的，改完自然就能打开了**。」

⇒ **这是有意的临时关闭，不是缺陷**。关闭理由是 Hermes 遗留问题（见已归档的 Hermes 调研笔记）。
⇒ **待办不是"改默认值"，而是"把 Hermes 那套的问题改完"** —— 改完默认值自然打开。
⇒ 本章 §4-1 的待拍板项**随之解除**（不再是选择，而是一个依赖关系）。

### 2.2 三类来源到 procedure 的映射（用户的三个例子）

| 用户说的 | 现有对应机制 | 缺口 / 裁定 |
|---|---|---|
| **「教训」**（踩过的坑） | `retracted` 条目 + `corrected` 证据 | **无自动通路** ⇒ ✅ **已裁定：教训进「候选」，不自动晋升，但可被检索**（见 §2.3） |
| **「攻关完成的项目」** | `episode.success === true` → `observe()`（`memory-hub-pre.js:132-148`）| 只有 `intent + 1 步「观察任务：…」`，**步骤质量不足**（issue30 的 P3 就修过"步骤1: user"垃圾） |
| **「多次重复的事件」** | `minSessions=3` + `minSuccess=2` 跨会话证据 | 机制**已有且合理** |

⇒ **最大缺口在第 1 行**，且已被用户裁定（§2.3）。

### 2.3 ★ 教训的晋升与检索（用户裁定 2026-09-18）

> 用户原话：「**教训**肯定得进 C 啊，它**不自动晋升**，但是**可以形成候选**，
> 模型也可以**通过搜索搜索到**。因为教训那边，我现在**自动注入的硬约束也是某种教训**，
> 把它**上升到了约束层面**。」

**裁定拆解**（agent 转写，若理解有偏差请纠正）：

| 层 | 教训的形态 | 是否自动晋升 | 模型如何拿到 |
|---|---|---|---|
| **候选（Candidate）** | 从 `retracted` / `correction` 证据生成的**观察型** procedure candidate | ❌ **永不自动晋升** | **主动搜索**（`memory_recall` 可检索到） |
| **skill** | 经证据闸门（`minSessions=3`/`minSuccess=2`）+ 人工审批后晋升 | 需人工 | **由官方流程注入**（见 §2.4） |
| **约束 / 规则** | 用户当前**自动注入的硬约束**——「**也是某种教训**，把它上升到了约束层面」 | 用户显式写 | 每轮自动注入（rules layer） |

**★ 这条裁定的关键洞察（本项最重要的一句）**：
**教训的终极形态不是 skill，而是"约束"**。用户当前系统里自动注入的硬约束
（记忆里的 `[规则 — 用户级硬性约束]` 层）**本质上就是教训升格后的产物**。
⇒ 所以本设计不是"新建一个教训系统"，而是**把既有的三层打通**：
`retracted 教训` →（候选，可检索）→（人工晋升）→ `skill` →（若足够普适）→ `约束/规则`。

### 2.4 ★ skill 的注入路径（用户两次澄清后的**最终版**）

**⚠️ agent 曾在上一稿下过头的结论（已更正）**：曾写「skill 注入归官方，插件不重复注入、
`act.skill` 段可能应改为只提供检索入口」—— **这是错的**。

**用户最终澄清（原话）**：

> 「印象这个 **skill 是相对比较独立的系统**，它**顶多会塞这个语义换回（召回）的时候
> 会换回这个 skill**。所以，**如果晋升成功，这个 skill 理论上应该是会被注入的**。」

**⇒ 正确理解（两条并行、互不冲突）**：

| | 官方 skills | **本插件的 procedure（skill）** |
|---|---|---|
| 归属 | DSH 官方技能系统 | **本插件，相对独立的系统** |
| 注入方式 | 官方流程（"会把所有 skills 当作注入"） | **经本插件的语义召回命中后附着注入** |
| 代码位置 | 官方 | `context-host-pre.js:524+`（query 匹配 active skill → `act.skill`）／<br>`activation-host-pre.js:300+`（Python 档 emit 帧）／`activation-inbox-pre.js` `renderSkillBlock` |
| 结论 | 与插件无关 | **✅ 晋升成功后，skill 会被本插件正常注入** |

**⇒ 对本设计的实际影响**：
1. **`act.skill` 段保持不变**，不是"应废弃" —— 它是本插件 skill 注入的**实现本体**。
   上一稿把它列为"待评估是否废弃"**作废**（BATTLE-PLAN §7 第 11 项随之撤销）。
2. 「不用占插件资源」的语境是**官方 skills 那一套**，**不适用于**本插件的 procedure；
   本插件 procedure 的注入走自己的语义召回，**该占的资源照占**（这是它的职责）。
3. **晋升 = 真正生效**：晋升成功后 skill 进入 `activeProcedures()`，被相似 query 命中后注入。
   ⇒ 这**加强了**审批责任感：审批界面「晋升后会怎样」那一栏要展示的正是
   **`renderChecklist()` 的真实文本**（§3.2 第 2 条），因为**那就是将来会被注入的内容**。


---

## 3. ★ 长期记忆审批：为什么"看不懂"（用户 ③）

用户原话：「**名字也不知道，流程是啥也不知道，没法审，只能盲确认通过**」。

### 3.1 现状（代码级）

「记忆中枢」页（`client.js:2552+`）对每条 pipeline 条目只展示：
`title` / `stage` / `riskLevel` / `evidence` + 三个按钮（晋升/激活/弃用/置顶）。

**缺的恰恰是审查所需的三样**：

| 审查需要知道 | 现状 | 后果 |
|---|---|---|
| **它是什么**（这条技能干什么） | 只有 `title`（≤40 字，还是从 `intent` 截断来的） | 名字看不出内容 |
| **凭什么该晋升**（证据） | 只有 `evidence` 计数的裸数字 | 不知道是哪几次会话、发生了什么 |
| **晋升后会怎样**（注入形态与代价） | 完全没展示 | 不知道点了会发生什么 |

⇒ **这不是 UI 品味问题，是"审查所需信息结构性地不在界面上"** ⇒ 只能盲确认。

### 3.2 设计方向（待细化，先记原则）

1. **展示「凭什么」**：把 `evidence` 从计数展开为**可点开的证据链**——
   哪几个 session、每次的 `kind`（success/correction）、对应的 episode 摘要。
   *（数据已在 `addEvidence` 里存着，只是没展示。）*
2. **展示「晋升后会注入什么」**：直接调 `renderChecklist(procedureId)` 把**将要注入的文本原样预览**。
   *（函数已存在，`activation-inbox-pre.js` 就在用它渲染。）*
3. **说人话**：`stage`/`riskLevel`/`observationOnly` 这些内部枚举要给**中文解释**，不能只显示代号。
4. **能反悔**：晋升错了要能撤回（与 G3 的「撤销通道 U1」同源纪律）。

> **与 G3 的关系**：G3 的 `restore`（撤销误标 superseded）与本项的「撤回误晋升」
> 是**同一个交互模式**——**凡自动/半自动改变结论状态的操作，都必须有人工回退通道且留痕**。

---

## 4. 待用户拍板 → ✅ **已全部拍板（2026-09-18）**

| # | 事项 | 用户裁定 |
|---|---|---|
| 1 | `procedurePromotionEnabled` 出厂默认 | ✅ **不是默认值问题**——是**有意临时关闭**（Hermes 遗留）。⇒ **待办改为"把 Hermes 那套的问题改完"，改完自然打开**（详见 §2.1） |
| 2 | 教训是否进 procedure | ✅ **「教训肯定得进 C 啊，它不自动晋升，但是可以形成候选，模型也可以通过搜索搜索到」** ⇒ **进候选 + 可检索 + 永不自动晋升**（详见 §2.3） |
| 3 | 注入侧是否也返回 | ✅ **随 I5 修正一并解决**（见 §2.4 + BATTLE-PLAN §10）：**检索侧一律返回+标记**；<br>本插件 procedure（skill）**晋升成功后经语义召回正常注入**，`act.skill` 段**保持不变** |
| 4 | 审批界面何时做 | ✅ 归口**前端重构**（与首次启动页一并） |

**⇒ 4 项全部解除，本设计稿无阻塞项。**

---

## 5. 归口与排期

| 事项 | 归口 | 时机 |
|---|---|---|
| I5 再修正（一律返回 + 标记 + 指向哈希） | R4-A | ✅ 边界已全部拍板，可开工（改动仍冻结） |
| 三条 issue #55–#58 修复 | 新增批次 | **前端重构之前**（用户裁定） |
| **Hermes 遗留问题修复**（打开 procedurePromotion 的前提） | 待立项 | ⬜ **新识别出的依赖项** |
| 教训 → 观察型候选（可检索、不自动晋升） | 待立项 | ⬜ 见 §2.3 |
| ~~评估 `act.skill` 段在官方接管后的定位~~ | — | ❌ **已撤销**：skill 是**相对独立的系统**，晋升成功后**会被本插件正常注入** ⇒ `act.skill` 段是**实现本体，保持不变** |
| **Hermes 遗留问题修复** | 待立项 | ⬜ **打开 procedurePromotion 的前提**（§2.1） |
| 审批界面重构（看懂"凭什么"） | **前端重构** | 与首次启动页一并 |
| 首次启动页重构 + 赞助商/中转站展示 | **前端重构** | 用户要求届时提醒 |

---

## 6. 本次三项裁定暴露的一条通用判据（供后续沿用）

> **agent 两次提出方案，两次被用户的"视角"推翻**：
> ① I5：agent 用**检索视角**（过时信息别干扰）→ 用户用**学习视角**（做错的事最该记）；
> ② procedurePromotion：agent 当**默认值 bug** → 实际是**有意的临时关闭**（依赖未修）。
>
> ⇒ **可复用教训：看到"配置是关的/行为是旧的"，先查它是不是"因为已知缺陷而故意关的"，
> 不要直接判定为疏漏。** 本仓已有先例（`memoryAnchorEnabled=false` 也是默认路径的关键开关），
> 这类"关着的开关"往往承载着未修复的依赖，**误判为 bug 会导致方向性错误**。

