# ④ 教训 → 观察型候选 · 引擎侧可行性核查（2026-09-19）

> 触发：按 `PRE-FRONTEND-CHECKLIST-20260919.md` 执行序推进 ④ 时的实施前核查。
> 方法：`artifacts/_probe-lesson-candidate.mjs`（**13/13**，执行真实 store，假 io 内存态，绝不碰磁盘）。

---

## 1. 用户裁定（设计稿 §2.3 原话）

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

⇒ 拆成**两条必须同时成立**的判据，加一条由设计稿推出的必然推论：

| 编号 | 判据 | 含义 |
|---|---|---|
| **L-1** | **不自动晋升** | 候选不受 `promote()` 通道影响 |
| **L-2** | **可被搜索到** | 候选可经 `query()` 取到 |
| **L-3** | **不被注入**（推论） | 未晋升 ⇒ 不进 `activeProcedures()` ⇒ 不进 checklist |

---

## 2. 核查结论：**L-1 / L-2 / L-3 引擎侧已全部满足**

`observationOnly:true` 这一机制**恰好就是**用户裁定的「不自动晋升的候选」形态：

| 判据 | 实证（探针编号） | 结果 |
|---|---|---|
| L-1 | `L-1-2` 把证据拉到**远超门槛**（`distinctSessions:99, successCount:99`）仍 `decision:'keep'`；`L-1-3` 原因码为 `observation-only`；`L-1-4` `stage` 未变 `validated` | ✅ |
| L-1（反证） | `L-1-5` **同等证据下普通候选确实晋升** ⇒ 隔离是**定向的**，不是"晋升通道整体坏掉" | ✅ |
| L-2 | `L-2-1` `query({})` 返回全部（含观察行）；`L-2-2` **可按 title 子串搜到**；`L-2-3` 结果携带 `observationOnly` 供调用方区分；`L-2-4` 可按 stage 过滤 | ✅ |
| L-3 | `L-3-1` 未 `active` ⇒ `renderChecklist()` 返回 `null`（**不会被注入**）；`L-3-2` `activeProcedures()` 为空 | ✅ |

> `L-1-5` 是本核查**最关键的一条**：只验"观察行不晋升"会与"引擎完全坏掉"不可区分（假绿）。加上反证才证明隔离是有效的。

---

## 3. ★ 真缺口：缺的是**生产者**，不是引擎

**探针 `L-4-1` 实测：全仓零处**把 `retracted` 条目派生成 procedure 候选。

现有 `retracted` 的消费点**只有一个**，且是 R4-A 刚落的**检索侧呈现标记**（`L-4-2`）：

```
lib/l0-extract-pre.js  L0_RETRACTED_MARK_PRE_V1  →  ⚠已撤回（原因：…；更正见 mem_…）
```

⇒ **缺口定位**：`retracted 教训` →（**缺失的生产者**）→ `observationOnly` 候选
→（已有）可检索／不晋升／不注入。

**引擎侧什么都不用改** —— 只需要一个**生产者**，把 `status:'retracted'` 的条目转成 `observe()` 的入参。

---

## 4. ⚠️ 但本项**不应由 agent 自行实现**

用户在 **2026-09-13** 明确（ZCode 项目记忆留档）:

> 「**任何 procedure 记忆引擎改动必须等用户拍板整体方案，别顺手修**」
> 「之前提议的两个小改点……已并入这次统一重构，**不单独做（动了也是白改）**」

而「加一个 retracted → 候选 的生产者」**正是 procedure 记忆引擎的功能改动**。

⇒ **本项的处置与 ③ 完全一致**：核查完成，**实现权交用户**。

---

## 5. 建议（不自行决定）

1. **④ 从「待立项」改为「引擎已就绪，待批复」** —— 前置条件（L-1/L-2/L-3）已实测满足，剩下的是**要不要加生产者**的决策。
2. 若批准，最小实现是：一处 `retracted` 扫描 → 构造 `{observationOnly:true, sourceEpisodes:[...], steps:['观察任务：<reason>']}` → `observe()`。
   - **零引擎改动**（复用现有 `observe` + `observationOnly` 语义）
   - **可被现有套件保护**（`promote()` 短路、`query()` 通路已有断言）
3. 与 ③ 的 **H-1**（上游是否真产富候选）**合并观测**：两者都在问「procedure 层的真实数据流量是多少」。若上游长期为空，先修 H-1 更有价值。

> ⚠️ 本项的**依赖链**：④ 的生产者若落地，会让 `procedures.json` 里出现大量 `observationOnly` 行 ——
> 而 `procedurePromotionEnabled` 目前**出厂 false**（③ H-2），故**不会**因此产生任何注入副作用。
> ⇒ ④ 与 ③ 是**同一条决策链**上的两环，宜一并拍板。
