@a9i5k4/dsh-auto-memory 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -7
- package/README.zh-CN.md +19 -7
- package/docs/FRONTEND-CO-CREATION.md +191 -0
- package/docs/GM53-HOMEPAGE-PROMPT.md +323 -0
- package/docs/HOMEPAGE-CONTENT-FOR-GM53.md +299 -0
- package/docs/PROMO-PROMPT-3.0.md +100 -0
- package/docs/USER-GUIDE.en.md +2 -2
- package/docs/USER-GUIDE.zh-CN.md +2 -2
- package/docs/WHITEPAPER.md +207 -0
- package/docs/internal/ARCHITECTURE-FOR-ZCODE-20260920.md +397 -0
- package/docs/internal/ART-DIRECTION-DEEPSEEK-20260920.md +351 -0
- package/docs/internal/ART-DIRECTION-WIREFRAME.md +191 -181
- package/docs/internal/ART-DIRECTION-WIREFRAME.md.bak-superseded +181 -0
- package/docs/internal/BATTLE-PLAN-20260917.md +871 -0
- package/docs/internal/FEATURE-INVENTORY.md +531 -0
- package/docs/internal/G-SERIES-EXECUTION-20260917.md +248 -0
- package/docs/internal/G3-DESIGN-20260918.md +82 -0
- package/docs/internal/G3-DISK-FORMAT-GAP-20260919.md +92 -0
- package/docs/internal/HANDOFF-TO-ZCODE-20260920.md +309 -0
- package/docs/internal/HERMES-DATA-VERIFICATION-20260919.md +120 -0
- package/docs/internal/HERMES-LEGACY-STATUS-20260919.md +74 -0
- package/docs/internal/ISSUE-55-58-VERIFICATION-20260918.md +175 -0
- package/docs/internal/ISSUE10-FIX-EXECUTION-20260919.md +389 -0
- package/docs/internal/ISSUE10-PLAN-20260919.md +254 -0
- package/docs/internal/ISSUE10B-FORENSICS-20260919.md +468 -0
- package/docs/internal/ISSUE9-PURGE-AND-R1-PLAIN-20260919.md +150 -0
- package/docs/internal/ISSUE9-RESIDUAL-FORENSICS-20260919.md +114 -0
- package/docs/internal/LESSON-TO-CANDIDATE-STATUS-20260919.md +79 -0
- package/docs/internal/MEMORY-GOVERNANCE-20260917.md +309 -0
- package/docs/internal/PRE-FRONTEND-CHECKLIST-20260919.md +705 -0
- package/docs/internal/PRE-FRONTEND-CHECKLIST-20260919.md.bak-s10 +649 -0
- package/docs/internal/PROCEDURAL-MEMORY-AND-APPROVAL-DESIGN-20260918.md +225 -0
- package/docs/internal/PROGRESS-20260917.md +93 -0
- package/docs/internal/PROMPT-GAP-AUDIT-20260920.md +128 -0
- package/docs/internal/R1-DEGRADE-AUDIT-20260918.md +163 -0
- package/docs/internal/R1-READABILITY-FORENSICS-20260919.md +127 -0
- package/docs/internal/R2-EVIDENCE-DEEP-AUDIT-20260918.md +140 -0
- package/docs/internal/R3-DEGRADE-LEDGER-DESIGN-20260918.md +138 -0
- package/docs/internal/R4-RECALL-QUOTA-PLAN-20260918.md +218 -0
- package/docs/internal/RESUME-20260918.md +171 -0
- package/docs/internal/RESUME-20260919.md +104 -0
- package/docs/internal/RHINELAB-TO-DEEPSEEK-FEASIBILITY.md +198 -0
- package/docs/internal/ROADMAP-20260917-WEEK.md +134 -0
- package/docs/internal/S10-CONSTRUCTION-HANDOFF-20260917.md +13 -3
- package/docs/internal/S10-GAP-INVENTORY-20260917.md +239 -0
- package/docs/internal/T6-EXECUTION-20260920.md +130 -0
- package/docs/internal/TELEMETRY-EFFECT-REPORT-DESIGN-20260918.md +146 -0
- package/docs/internal/THESIS-GAP-ANALYSIS-20260918.md +89 -0
- package/docs/internal/THESIS-OUTLINE-20260918.md +147 -0
- package/docs/internal/THREE-LAYER-CONTRACT.md +10 -1
- package/docs/internal/UPSTREAM-ISSUE-PR-TRIAGE-20260919.md +297 -0
- package/docs/internal/UPSTREAM-ISSUES-3RD-AUDIT-20260920.md +104 -0
- package/docs/screenshots/promo/promo-0-banner-v3.png +0 -0
- package/lib/activation-host.js +63 -9
- package/lib/board-mode.js +1 -1
- package/lib/client.js +892 -27
- package/lib/config-io.js +156 -0
- package/lib/context-bridge.js +3 -0
- package/lib/context-host.js +16 -9
- package/lib/degrade.js +385 -0
- package/lib/dsh-home.js +143 -0
- package/lib/episodic-store.js +52 -2
- package/lib/evidence-store.js +8 -1
- package/lib/fact-store.js +21 -2
- package/lib/index-sync.js +13 -1
- package/lib/index.js +1507 -158
- package/lib/intent-clean-safe.js +258 -40
- package/lib/l0-extract.js +231 -16
- package/lib/m4-corpus.js +8 -2
- package/lib/m7-index-sync-host.js +8 -1
- package/lib/memory-envelope.js +6 -1
- package/lib/memory-hub.js +127 -12
- package/lib/memory-index.js +4 -2
- package/lib/note-status-apply.js +118 -0
- package/lib/note-status.js +196 -0
- package/lib/procedure-store.js +84 -3
- package/lib/python-sidecar-client.js +29 -3
- package/lib/recall-fusion.js +83 -12
- package/lib/rules-edit.js +159 -0
- package/lib/semantic-decide.js +41 -8
- package/lib/semantic-js.js +51 -6
- package/lib/shadow-host.js +3 -5
- package/lib/skill-export-host.js +153 -0
- package/lib/skill-export.js +239 -0
- package/lib/storage-manage.js +6 -0
- package/lib/temporal-parse.js +191 -159
- package/lib/tier0-catalog.js +45 -3
- package/lib/wb-contract.js +198 -2
- package/lib/wb-sidecar.js +54 -3
- package/package.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# ⑨ 漏网追加取证(2026-09-19 22:40 · 真机实测)
|
|
2
|
+
|
|
3
|
+
> **性质**:⑨ 修复后**新产生**的脏数据。不是存量,是**活的漏网证据**。
|
|
4
|
+
> **发现方式**:用户截图「技能审批队列 (5)」,主代理实测宿主内存发现数字**真的回到了 5**。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 0. 实测数据(`GET /api/dsh-auto-memory-pre/memory-hub`)
|
|
9
|
+
|
|
10
|
+
| 指标 | ⑨ 清理后(20:15) | **现在(22:40)** |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| `procedures.size` | 12 | **14** |
|
|
13
|
+
| `pipeline`(会进注入路径) | **3** | **5** |
|
|
14
|
+
| `active` | 1 | 1 |
|
|
15
|
+
|
|
16
|
+
**pipeline 逐条**(`obs=True` 即 `observationOnly`):
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
[observed] 让我自己去试吧。现在是什么情况? obs=True ← 旧(真人文本)
|
|
20
|
+
[observed] 开始实施 obs=True ← 旧(真人文本)
|
|
21
|
+
[observed] 开始实施,实施完给我准确的报告保证我能看懂 obs=True ← 旧(真人文本)
|
|
22
|
+
[observed] Source: me obs=True ← ★ 新漏网
|
|
23
|
+
[observed] Reference: ## 2026-09-18 - dsh-auto-memo obs=True ← ★ 新漏网
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**⇒ ⑨ 修好的判据挡住了 8 条存量,但挡不住这两个新形态。**
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 1. 根因:判据「太具体」——把「前缀」和「内容」绑死了
|
|
31
|
+
|
|
32
|
+
⑨ 落地的 F3(`lib/intent-clean-safe-pre.js`):
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
const PLUGIN_TAIL_MARKER_RE = /^\[?Retrieved memory ref
|
|
36
|
+
|^Verify against the current user request
|
|
37
|
+
|^If a reference hints at what you need
|
|
38
|
+
|^Source:\s*mem_[0-9a-f]{32} // ← ★ 问题在这
|
|
39
|
+
|^Reason:\s*fv2 lane=
|
|
40
|
+
|^Score:\s*[0-9.]+ \(rank \d+\/\d+\)/i
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**`^Source:\s*mem_[0-9a-f]{32}`** —— 它要求 `Source:` **后面必须紧跟合法的 `mem_<32hex>`**。
|
|
44
|
+
|
|
45
|
+
而漏网的这条是 **`Source: me`**:
|
|
46
|
+
- `Source:` 后面不是 `mem_<32hex>`
|
|
47
|
+
- ⇒ **判据不匹配 ⇒ 放行**
|
|
48
|
+
|
|
49
|
+
**同理**:`Reference: ## 2026-09-18 - dsh-auto-memo` —— F3 里**根本没有 `^Reference:` 这一条**
|
|
50
|
+
(只有 `^\[?Retrieved memory ref`,那是召回块的**首行**,不是 `Reference:` 行)。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 2. ★ 这两条是怎么产生的(推断,附证据方向)
|
|
55
|
+
|
|
56
|
+
**推断(基于形态)**:它们来自**召回块被截断后的残片**。
|
|
57
|
+
召回块的完整形态包含 `Source: mem_<32hex> / <scope> / v<n> / <digest>` 与 `Reference: <正文片段>` 两类行。
|
|
58
|
+
当这些行**作为 intent 的一部分被截断**(`slice(0, 40)`,见 `memory-hub-pre.js:155`)时:
|
|
59
|
+
|
|
60
|
+
- `Source: mem_abc123...` 被截 → `Source: me`
|
|
61
|
+
- `Reference: ## 2026-09-18 - dsh-auto-memo...` 被截 → 标题即截断结果
|
|
62
|
+
|
|
63
|
+
**⇒ 截断让「内容判据」失效**,但**前缀 `Source:` / `Reference:` 仍然完好**。
|
|
64
|
+
|
|
65
|
+
**关键教训(与 ⑨ 的 F3 设计初衷直接冲突)**:
|
|
66
|
+
> ⑨ 的注释里明写「**判据是族(family)+ 形状,不是整句前缀** ⇒ 框架换措辞仍能被同一个族覆盖」。
|
|
67
|
+
> **但 F3 的实际实现把「前缀」和「后缀内容」绑死了** ⇒ 一旦被截断,就漏。
|
|
68
|
+
> **这正是 ⑨ 自己批评过的错误模式,在 F3 上复发了一次。**
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3. 修法(**尚未动手,待与 ⑩ 一并处理**)
|
|
73
|
+
|
|
74
|
+
**方向**:F3 应改为 **「前缀即判据」**,不要求后缀形态:
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
// 现状(过严,被截断即漏)
|
|
78
|
+
|^Source:\s*mem_[0-9a-f]{32}
|
|
79
|
+
|
|
80
|
+
// 应为(前缀族,后缀不约束)
|
|
81
|
+
|^Source:\s*\S // 或更严格:^Source:\s*(mem_|me\b|epi_|session)
|
|
82
|
+
|^Reference:\s*\S // ← 新增,F3 目前完全没有这一条
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**⚠️ 必须同时守住误伤边界**(⑨ 套件 [4] 组守的就是这条):
|
|
86
|
+
- 「帮我看看 `[Retrieved memory reference]` 这个标记是干嘛的」**不得被删**
|
|
87
|
+
- ⇒ 前缀判据必须**要求 `Source:`/`Reference:` 位于行首**(`^` 锚定保留),
|
|
88
|
+
且**不得**把正文里出现的普通 `Source:` 误判
|
|
89
|
+
- ⇒ 建议**加 `\s*\S`(后面必须跟非空内容)**,避免把孤立的 `Source:` 也吞掉
|
|
90
|
+
|
|
91
|
+
**验收要求**:
|
|
92
|
+
1. 新增套件用例:`Source: me` / `Reference: ## 2026-09-18 - dsh-auto-memo` **必须被判脏**
|
|
93
|
+
2. 反向用例:正文中的 `Source:` / `Reference:` **不得**被误删(沿用 ⑨ 套件 [4] 组口径)
|
|
94
|
+
3. 变异演示真红
|
|
95
|
+
4. 全量回归 0 失败
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 4. 与既有计划的关系
|
|
100
|
+
|
|
101
|
+
| 项 | 关系 |
|
|
102
|
+
|---|---|
|
|
103
|
+
| **⑨** | **判定为「修得不完整」** ⇒ 需追加一轮 F3 判据修正(本文件即其取证) |
|
|
104
|
+
| **⑩-a / ⑩-b** | **同源**:fact 分支同样未清洗 ⇒ 本次一并修 |
|
|
105
|
+
| **存量 2 条新脏** | 与 ⑩-b 的「存量 3 条 fact」处置同源 ⇒ **同样走路 C(靠卫生门堵住)** |
|
|
106
|
+
|
|
107
|
+
**⇒ 建议把「F3 前缀判据修正」并入 ⑩ 那一批一起做**,因为它们都在 `memory-hub-pre.js` 的同一条链路上。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 5. 取证边界
|
|
112
|
+
- 本文所有 `procedures.size / pipeline / title` 均为**实测**(`GET /api/dsh-auto-memory-pre/memory-hub`,2026-09-19 22:40)。
|
|
113
|
+
- 「这两条来自召回块截断残片」为**推断**,依据是形态与 `memory-hub-pre.js:155` 的 `slice(0, 40)`;
|
|
114
|
+
未逐条回溯其 `sourceEpisodes` 确认。
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# ④ 教训 → 观察型候选 · 引擎侧可行性核查(2026-09-19)
|
|
2
|
+
|
|
3
|
+
> 触发:按 `PRE-FRONTEND-CHECKLIST-20260919.md` 执行序推进 ④ 时的实施前核查。
|
|
4
|
+
> 方法:`artifacts/_probe-lesson-candidate.mjs`(**13/13**,执行真实 store,假 io 内存态,绝不碰磁盘)。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. 用户裁定(设计稿 §2.3 原话)
|
|
9
|
+
|
|
10
|
+
> 「**教训**肯定得进 C 啊,它**不自动晋升**,但是**可以形成候选**,
|
|
11
|
+
> 模型也可以**通过搜索搜索到**。因为教训那边,我现在自动注入的硬约束也是某种教训,
|
|
12
|
+
> 把它**上升到了约束层面**。」
|
|
13
|
+
|
|
14
|
+
⇒ 拆成**两条必须同时成立**的判据,加一条由设计稿推出的必然推论:
|
|
15
|
+
|
|
16
|
+
| 编号 | 判据 | 含义 |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| **L-1** | **不自动晋升** | 候选不受 `promote()` 通道影响 |
|
|
19
|
+
| **L-2** | **可被搜索到** | 候选可经 `query()` 取到 |
|
|
20
|
+
| **L-3** | **不被注入**(推论) | 未晋升 ⇒ 不进 `activeProcedures()` ⇒ 不进 checklist |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2. 核查结论:**L-1 / L-2 / L-3 引擎侧已全部满足**
|
|
25
|
+
|
|
26
|
+
`observationOnly:true` 这一机制**恰好就是**用户裁定的「不自动晋升的候选」形态:
|
|
27
|
+
|
|
28
|
+
| 判据 | 实证(探针编号) | 结果 |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| L-1 | `L-1-2` 把证据拉到**远超门槛**(`distinctSessions:99, successCount:99`)仍 `decision:'keep'`;`L-1-3` 原因码为 `observation-only`;`L-1-4` `stage` 未变 `validated` | ✅ |
|
|
31
|
+
| L-1(反证) | `L-1-5` **同等证据下普通候选确实晋升** ⇒ 隔离是**定向的**,不是"晋升通道整体坏掉" | ✅ |
|
|
32
|
+
| L-2 | `L-2-1` `query({})` 返回全部(含观察行);`L-2-2` **可按 title 子串搜到**;`L-2-3` 结果携带 `observationOnly` 供调用方区分;`L-2-4` 可按 stage 过滤 | ✅ |
|
|
33
|
+
| L-3 | `L-3-1` 未 `active` ⇒ `renderChecklist()` 返回 `null`(**不会被注入**);`L-3-2` `activeProcedures()` 为空 | ✅ |
|
|
34
|
+
|
|
35
|
+
> `L-1-5` 是本核查**最关键的一条**:只验"观察行不晋升"会与"引擎完全坏掉"不可区分(假绿)。加上反证才证明隔离是有效的。
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 3. ★ 真缺口:缺的是**生产者**,不是引擎
|
|
40
|
+
|
|
41
|
+
**探针 `L-4-1` 实测:全仓零处**把 `retracted` 条目派生成 procedure 候选。
|
|
42
|
+
|
|
43
|
+
现有 `retracted` 的消费点**只有一个**,且是 R4-A 刚落的**检索侧呈现标记**(`L-4-2`):
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
lib/l0-extract-pre.js L0_RETRACTED_MARK_PRE_V1 → ⚠已撤回(原因:…;更正见 mem_…)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
⇒ **缺口定位**:`retracted 教训` →(**缺失的生产者**)→ `observationOnly` 候选
|
|
50
|
+
→(已有)可检索/不晋升/不注入。
|
|
51
|
+
|
|
52
|
+
**引擎侧什么都不用改** —— 只需要一个**生产者**,把 `status:'retracted'` 的条目转成 `observe()` 的入参。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 4. ⚠️ 但本项**不应由 agent 自行实现**
|
|
57
|
+
|
|
58
|
+
用户在 **2026-09-13** 明确(ZCode 项目记忆留档):
|
|
59
|
+
|
|
60
|
+
> 「**任何 procedure 记忆引擎改动必须等用户拍板整体方案,别顺手修**」
|
|
61
|
+
> 「之前提议的两个小改点……已并入这次统一重构,**不单独做(动了也是白改)**」
|
|
62
|
+
|
|
63
|
+
而「加一个 retracted → 候选 的生产者」**正是 procedure 记忆引擎的功能改动**。
|
|
64
|
+
|
|
65
|
+
⇒ **本项的处置与 ③ 完全一致**:核查完成,**实现权交用户**。
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 5. 建议(不自行决定)
|
|
70
|
+
|
|
71
|
+
1. **④ 从「待立项」改为「引擎已就绪,待批复」** —— 前置条件(L-1/L-2/L-3)已实测满足,剩下的是**要不要加生产者**的决策。
|
|
72
|
+
2. 若批准,最小实现是:一处 `retracted` 扫描 → 构造 `{observationOnly:true, sourceEpisodes:[...], steps:['观察任务:<reason>']}` → `observe()`。
|
|
73
|
+
- **零引擎改动**(复用现有 `observe` + `observationOnly` 语义)
|
|
74
|
+
- **可被现有套件保护**(`promote()` 短路、`query()` 通路已有断言)
|
|
75
|
+
3. 与 ③ 的 **H-1**(上游是否真产富候选)**合并观测**:两者都在问「procedure 层的真实数据流量是多少」。若上游长期为空,先修 H-1 更有价值。
|
|
76
|
+
|
|
77
|
+
> ⚠️ 本项的**依赖链**:④ 的生产者若落地,会让 `procedures.json` 里出现大量 `observationOnly` 行 ——
|
|
78
|
+
> 而 `procedurePromotionEnabled` 目前**出厂 false**(③ H-2),故**不会**因此产生任何注入副作用。
|
|
79
|
+
> ⇒ ④ 与 ③ 是**同一条决策链**上的两环,宜一并拍板。
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# 记忆治理与接续质量 · 专项攻关纲领
|
|
2
|
+
|
|
3
|
+
> 2026-09-17 定稿 · 用户明确列为**重点攻关项目**
|
|
4
|
+
> 上游:`BATTLE-PLAN-20260917.md`(执行顺序权威)、`S10-GAP-INVENTORY-20260917.md`(缺口复核)
|
|
5
|
+
> 本文档管辖范围:**记忆正确性治理**(大象)+ **接续材料质量**(白板结构)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 0. 为什么单独开一份文档
|
|
10
|
+
|
|
11
|
+
用户原话(2026-09-17):
|
|
12
|
+
|
|
13
|
+
> "如果老记忆是错的,新记忆更正了;或者新记忆更新了,老记忆不适用,这种情况怎么办?
|
|
14
|
+
> 我一直在这个过去的对话和项目文档中提过类似的焦虑,但可能每次 AI 提出的回馈,我都没有及时修改或者没有来得及采纳。"
|
|
15
|
+
|
|
16
|
+
**这不是新问题,是长期未被处理的欠账。** 现有 12 个记忆工具**没有任何一个**能回答"这条记忆还成立吗"。
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. 大象的实证:活体标本(不是推测)
|
|
21
|
+
|
|
22
|
+
**实测位置**:`~/.dsh/memory/workspaces/--D--dsh-auto-memory--/MEMORY.md`(19610 字节 / 203 行)
|
|
23
|
+
|
|
24
|
+
同一份文件内,三条结论**互相矛盾且并存**:
|
|
25
|
+
|
|
26
|
+
| 行 | 内容 | 状态 |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| **120** | 「逐处判读后结论 —— **真正该解耦的只有 2 处**:`:1993`、`:2037`」 | ❌ **已作废** |
|
|
29
|
+
| **161-162** | 「**那个结论划窄了范围**:只枚举了 `boardMode` 一族,**漏掉并行的 `handoffEnabled` 一族**」 | ✅ 修正声明 |
|
|
30
|
+
| **183** | 「13 处闸门逐条判归属后:**只需动 4 处**」 | ✅ 现行结论 |
|
|
31
|
+
|
|
32
|
+
**危害**:行 120 排在**最前、语气最肯定**("逐处判读后结论"),下一个窗口极可能据此按"2 处"施工,**漏掉两处 handoffEnabled 渲染闸门**——正是用户报障的那条线。
|
|
33
|
+
|
|
34
|
+
**这证明三件事**:
|
|
35
|
+
1. 矛盾确实会产生,且**已经产生**;
|
|
36
|
+
2. 修正**确实写了**,但**没有作废旧条目**(append 语义的固有缺陷);
|
|
37
|
+
3. 记忆是**纯文本追加**,无版本、无作废标记、无 supersede 链。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 2. 根因:append-only 与"结论会变"的根本冲突
|
|
42
|
+
|
|
43
|
+
| 层 | 现有机制 | 为什么不够 |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| 日志 | `memory_log_pre` append-only | 追加是**正确**的(日志本就该流水) |
|
|
46
|
+
| 项目笔记 | `memory_note_pre` append | ⚠️ **笔记不是流水,是结论**,但用了流水的语义 |
|
|
47
|
+
| 用户级 | `memory_user_pre` append | 同上 |
|
|
48
|
+
| 白板 | `memory_note_pre(kind=plan)` **replace** | ✅ **唯一有 replace 语义的层** |
|
|
49
|
+
|
|
50
|
+
**结论**:只有白板支持"重写即替换"。**笔记/用户级只有 append ⇒ 旧结论永远留存 ⇒ 矛盾必然累积。**
|
|
51
|
+
|
|
52
|
+
而现有"整理"机制(超容量时 AI 折叠成要点)**只在超限时触发**——19610 字节**远未触顶 12000 字符上限**(注:实际已超,见 §2.1),且折叠**不保证识别矛盾**,只做压缩。
|
|
53
|
+
|
|
54
|
+
### 2.1 容量口径已核实:**未超限,机制正常**(2026-09-17 实测)
|
|
55
|
+
|
|
56
|
+
| 口径 | 值 |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `MEMORY.md` 文件字节 | 19610 字节 |
|
|
59
|
+
| **实际字符数**(`raw.Length`) | **11956 字符** |
|
|
60
|
+
| 默认上限 `noteCapacityChars` | **12000 字符** |
|
|
61
|
+
| 判定 | ✅ **未超,余量仅 44 字符** |
|
|
62
|
+
|
|
63
|
+
**关键**:容量按**字符**计,不按字节。中文字符 UTF-8 占 3 字节 ⇒ 字节数约为字符数的 1.6 倍,故 19610 字节 ≠ 超限。
|
|
64
|
+
|
|
65
|
+
**⚠️ 但余量只有 44 字符** ⇒ **下一次写入几乎必然触发整理**。
|
|
66
|
+
⇒ 这意味着整理机制**即将被实际检验**,其"折叠是否会识别矛盾"的能力(§2 指出的弱点)**马上要在真实数据上见分晓**。
|
|
67
|
+
⇒ **建议**:在下次写入前先人工确认行 120 作废标记已加,**避免整理把作废结论折叠成"要点"而失去作废语义**。
|
|
68
|
+
|
|
69
|
+
*(更正记录:本节初稿曾据字节数误判为"已超限 63%、疑似 bug",实测后推翻。属推理未取证即下结论,已按纪律更正。)*
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 3. 攻关方案(三层,按成本递增)
|
|
74
|
+
|
|
75
|
+
### 3.1 方案 A(最小可用)· 结论条目带「有效期 + 作废指针」
|
|
76
|
+
|
|
77
|
+
**不引入新存储**,只在写笔记时约定格式:
|
|
78
|
+
|
|
79
|
+
```markdown
|
|
80
|
+
### 2026-09-17 · 白板线解耦边界
|
|
81
|
+
<!-- id: mem_xxx supersedes: mem_yyy status: current -->
|
|
82
|
+
结论:只需动 4 处...
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- `id` = 现有锚点(**已有**,`<!-- memory:mem_32hex -->`)
|
|
86
|
+
- `supersedes:` = 本条作废了哪些 id(**新字段**)
|
|
87
|
+
- `status:` = `current` / `superseded` / `deprecated`(**新字段**)
|
|
88
|
+
|
|
89
|
+
**检索时**:命中 `status != current` 的条目 ⇒ **降权或标注"(已作废,见 <新id>)"**。
|
|
90
|
+
|
|
91
|
+
**成本**:改 `memory_note_pre` 写入模板 + `pushL0`/`semSources` 读取时过滤。**零新增文件、零 LLM 调用。**
|
|
92
|
+
|
|
93
|
+
### 3.2 方案 B(主动巡检)· 矛盾检测 lint
|
|
94
|
+
|
|
95
|
+
复用已规划的 **M2 lint** 思路(只读、只报告、绝不写盘):
|
|
96
|
+
- 扫描笔记/用户级记忆,找**同一主题下的多条结论**
|
|
97
|
+
- 条件触发(非每轮),只在**写入新结论**时检查是否与旧结论冲突
|
|
98
|
+
- 输出:"检测到可能的结论冲突:`mem_A`(2026-09-16,2 处)vs `mem_B`(2026-09-17,4 处)"
|
|
99
|
+
|
|
100
|
+
**成本**:中。需定义"同主题"判据(tag / 标题相似度)。**③④ 判据待用户拍板**(已在 BATTLE-PLAN 待决项中)。
|
|
101
|
+
|
|
102
|
+
### 3.3 方案 C(根治)· 结论层与流水层分离
|
|
103
|
+
|
|
104
|
+
**识别到根本矛盾**:
|
|
105
|
+
> 日志 = 流水(append 正确);笔记 = 结论(append 错误)。
|
|
106
|
+
|
|
107
|
+
⇒ **拆分语义**:
|
|
108
|
+
- `logs/` 保持 append-only(不动)
|
|
109
|
+
- `MEMORY.md` **改为"活结论文档"**:写入新结论时,**同主题旧结论自动移入 `archive/conclusions-<date>.md`**
|
|
110
|
+
|
|
111
|
+
**这等于把白板的 `replace + archive` 语义推广到笔记层**——而**该机制已经存在且经过验证**(`:1984` PLAN 重写归档、`:2011`)。
|
|
112
|
+
|
|
113
|
+
**成本**:高,但**复用现成机制**,不是新建。
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 4. 用户另一个问题:增删改现状(纠正我此前的浅显回答)
|
|
118
|
+
|
|
119
|
+
**我此前只答了"没有删除工具"——太浅。** 补全:
|
|
120
|
+
|
|
121
|
+
| 能力 | 状态 | 位置 |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| **增** | ✅ 完整 | `memory_log/note/user_pre` |
|
|
124
|
+
| **读** | ✅ 完整 | `memory_read/recall/status_pre` |
|
|
125
|
+
| **改(覆盖式)** | ⚠️ **仅白板** | `memory_note_pre(kind=plan)` = replace |
|
|
126
|
+
| **改(笔记/用户级)** | ❌ **只能 append,无法改写已有结论** | —— |
|
|
127
|
+
| **删(硬删)** | ❌ 无,**且按设计不该有** | —— |
|
|
128
|
+
| **作废(软删)** | ❌ **无任何机制** | —— |
|
|
129
|
+
| **归档** | ✅ 有 | PLAN 重写、超容量整理 |
|
|
130
|
+
| **语义重排** | ✅ **不需要** | `miv` 指纹变才重算,`:4719-4748` |
|
|
131
|
+
|
|
132
|
+
**关键结论**:
|
|
133
|
+
1. **不存在"删记忆搞崩语义库"的风险**——没有硬删,且 miv **不因内容变化全量重建**(只在指纹变时 fail-closed 不复用)。
|
|
134
|
+
2. **但有更隐蔽的风险**:**改不了** ⇒ 错结论只能靠"再写一条对的"来对冲 ⇒ **正是一号标本的成因**。
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 5. 白板结构评估(用户第二问)
|
|
139
|
+
|
|
140
|
+
### 5.1 实测现状
|
|
141
|
+
| 文件 | 体积 | 行数 | 更新频率 |
|
|
142
|
+
|---|---|---|---|
|
|
143
|
+
| `PLAN.md` | **1506 字符** | 23 行 | 每次接续重写 |
|
|
144
|
+
| `handoff-*.md` | 2922 字节 | ~30 行 | 每次接续新增 |
|
|
145
|
+
|
|
146
|
+
**用户判断"量肯定是够了"—— 实测支持这个判断**:1506 字符远未触及 3000 预算。
|
|
147
|
+
|
|
148
|
+
### 5.2 但结构有真问题
|
|
149
|
+
|
|
150
|
+
**问题一:PLAN.md 是"项目说明书",不是"交接单"**
|
|
151
|
+
现内容 = 项目介绍 + 3.0 历史 + 阶段列表。**这些是"是什么/从哪来",不是"现在卡在哪、下一步做什么"。**
|
|
152
|
+
⇒ 下一个窗口读完知道项目背景,**但不知道手头活的精确状态**。
|
|
153
|
+
|
|
154
|
+
**问题二:交接账本与 PLAN.md 职责重叠**
|
|
155
|
+
PLAN.md 有"遗留与边界(给下一个窗口)",账本有"进度与下一步"。**两处都写下一步 ⇒ 可能不同步(又一个小号大象)。**
|
|
156
|
+
|
|
157
|
+
**问题三:账本按时间文件名排列,但内容无"承接关系"**
|
|
158
|
+
`handoff-20260917-023635.md` 起头写"# 交接账本 · 2026-09-16 02:36"(**文件名日期与标题日期不一致**,因为文件名用写入时刻、标题用内容时刻)。⇒ **按文件名排序 ≠ 按内容时序**。
|
|
159
|
+
|
|
160
|
+
**问题四:无"已作废"标记**
|
|
161
|
+
老账本里的"下一步"如果已被新账本取代,**老账本无任何标记**,检索到会误导。
|
|
162
|
+
|
|
163
|
+
### 5.3 结构建议(不增量,只调分工)
|
|
164
|
+
|
|
165
|
+
| 账户 | 应写什么 | 不应写什么 |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| `PLAN.md` | **稳定事实**:这是什么、架构、铁律、边界。低频重写 | 不写"下一步" |
|
|
168
|
+
| `handoff-*.md` | **动态状态**:卡在哪、试过什么、下一步(**唯一权威**) | 不重复项目介绍 |
|
|
169
|
+
| `MEMORY.md` | **可复用结论** + `supersedes` 链 | 不写流水 |
|
|
170
|
+
|
|
171
|
+
**即:下一步只在一个地方写。** 这消除问题二/三/四。
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 6. 执行顺序(并入 BATTLE-PLAN,不打断 L 层)
|
|
176
|
+
|
|
177
|
+
用户已批准主线:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
L3.5(附件路径)→ L4 → L5 → L6 → L7 → 全量回归绿 → 再开 L3.6
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**本文档的攻关项**(建议编号 **G 系列**,与 L/M/S 并列,独立推进):
|
|
184
|
+
|
|
185
|
+
| 项 | 内容 | 依赖 | 优先级 |
|
|
186
|
+
|---|---|---|---|
|
|
187
|
+
| **G1** | 核实容量口径(§2.1):19610 字节为何未触发整理 | 无 | 🔴 立即(疑似 bug) |
|
|
188
|
+
| **G2** | 一号标本处置:给 MEMORY.md 行 120 补作废标记 | 无 | 🔴 立即(防误用) |
|
|
189
|
+
| **G3** | 方案 A:结论条目 `supersedes`/`status` 约定 + 读取时过滤 | 无 | 🟡 **已定案 → 并入 M2(见 §8)** |
|
|
190
|
+
| **G4** | 白板分工调整(§5.3):下一步只在账本写 | 无 | ✅ **已完工**(三层分工已进 GUIDANCE) |
|
|
191
|
+
| **G5** | 方案 B:矛盾 lint(复用于 M2) | 无(判据改由"主动触发 + 写入兜底",见 §8.4) | 🟢 **与 G3 同批 → 并入 M2** |
|
|
192
|
+
| **G6** | 方案 C:结论层 replace+archive 语义 | G3 落地后 | 🟢 长期 |
|
|
193
|
+
|
|
194
|
+
**L3.6**(旧对话可检索化)保持原定位置,不属于本文档管辖。
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 7. 待用户拍板(历史记录 · 均已裁定)
|
|
199
|
+
|
|
200
|
+
1. ~~**G1 是否立即查**~~ → 已查:容量口径**未超限**(§2.1 已更正),非 bug。
|
|
201
|
+
2. ~~**G2 是否立即处置**~~ → 已处置(`MEMORY.md.bak-20260917-G2` 留档)。
|
|
202
|
+
3. ~~**G3 的 `supersedes` 自动还是手写**~~ → **已拍板:只在结论层(`memory_note_pre`)自动比对**,见 §8.2。
|
|
203
|
+
4. ~~**§5.3 分工调整是否同意**~~ → 已同意并落地为 G4(三层分工进 GUIDANCE)。
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 8. G3+G5 合并设计(2026-09-18 用户拍板)
|
|
208
|
+
|
|
209
|
+
**用户原话**:「b➕c 应该才是正路,每次 memory-log 的时候都应该语义臂检索更新纠正记忆」+「(b) 只在 `memory_note_pre`(结论层)时比对」+「标错成 superseded 后,要不要有个撤销通道?**落到文档里,和 M2 一起做**」。
|
|
210
|
+
|
|
211
|
+
### 8.1 关键前置事实:地基已经存在(本次实测,附代码证据)
|
|
212
|
+
|
|
213
|
+
**这不是从零造轮子——机制早已建好,只是从来没有被接线。**
|
|
214
|
+
|
|
215
|
+
| # | 事实 | 证据 |
|
|
216
|
+
|---|---|---|
|
|
217
|
+
| 1 | **`status` 三值已定义**,与契约 §6 完全一致 | `l0-extract-pre.js:56` `L0_STATUSES = ['current','superseded','retracted']` |
|
|
218
|
+
| 2 | **`layer` 五值已定义** | `l0-extract-pre.js:53` `L0_LAYERS = ['user','project','log','reflection','whiteboard']` |
|
|
219
|
+
| 3 | **L0 索引已带 status 列,且进版本指纹** | `l0-index-pre.js:62` canonical `[id, l0Hash, layer, status]` → `l0idx_pre_<sha256前32>` |
|
|
220
|
+
| 4 | **改 status 会自动失效下游缓存** | 同上:状态进指纹 ⇒ 版本变 ⇒ 缓存 fail-closed 不复用 |
|
|
221
|
+
| 5 | **兼容口径已定**:缺失即默认 | `l0-index-pre.js:35` `layer→log` / `status→current`,**不因缺列拒绝整文件**,旧索引照常加载 |
|
|
222
|
+
| 6 | ★ **但没有任何地方在写这两个字段** | 全仓写 `status` 只有 2 处:`tier0-catalog-pre.js:283`、`wb-contract-pre.js:186`,**均为硬编码 `'current'`** |
|
|
223
|
+
|
|
224
|
+
> **结论**:缺口不是"没有机制",而是「**机制只读不写**」。零处写 `superseded`/`retracted`。
|
|
225
|
+
> ⇒ 所以 G3 的工程量远小于方案 A 当时的估计:**不需要改 L0 索引、不需要改版本指纹、不需要动读取侧过滤**——那些全都有了。
|
|
226
|
+
|
|
227
|
+
### 8.2 触发范围(用户裁定:**只在结论层**)
|
|
228
|
+
|
|
229
|
+
**只挂 `memory_note_pre`,不挂 `memory_log_pre`。**
|
|
230
|
+
|
|
231
|
+
理由(与 §2 根因表同源):
|
|
232
|
+
- **日志 = 流水**,append 是**正确**语义,流水里不存在"这条日志作废了另一条日志"的概念;
|
|
233
|
+
- **笔记 = 结论**,append 是**错误**语义,才是矛盾的滋生地。
|
|
234
|
+
|
|
235
|
+
> ⚠️ 用户原话提到"每次 memory-log 的时候" —— 但随后自己修正为「只在 `memory_note_pre`」。
|
|
236
|
+
> **以 `memory_note_pre` 为准**,这是更小、更准的落点;日志路径保持零改动(也符合"最热路径不加成本")。
|
|
237
|
+
|
|
238
|
+
**链路(四环中三环已有现成机制)**:
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
memory_note_pre(结论) 被调用
|
|
242
|
+
↓
|
|
243
|
+
① 语义臂检索同主题旧条目 ← 已有:recallMemoryPre 的 semSources
|
|
244
|
+
↓
|
|
245
|
+
② 判定"本条取代了哪条" ← ★ 唯一新增:判定 + 写状态
|
|
246
|
+
↓
|
|
247
|
+
③ 给旧条目写 status='superseded' ← 字段已有,只差写入方
|
|
248
|
+
↓
|
|
249
|
+
④ L0 版本自动变 ⇒ 缓存自动失效 ← 已有:状态进指纹
|
|
250
|
+
↓
|
|
251
|
+
⑤ 旧条目归档 ← 已有:复用 PLAN 的 replace+archive
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 8.3 撤销通道(用户提问,**需要设计**)
|
|
255
|
+
|
|
256
|
+
**问题**:自动标错 `superseded` 后怎么改回来?
|
|
257
|
+
|
|
258
|
+
**必须有的理由**:**误判的代价不对称** —— 漏判只是"矛盾继续存在"(回到现状,可接受);**误判会把一条还有效的结论标成作废,比不改更糟**(下一个窗口会无视它)。所以撤销通道是**必需项**,不是可选项。
|
|
259
|
+
|
|
260
|
+
**设计(三条,择一或组合,实施前定稿)**:
|
|
261
|
+
|
|
262
|
+
| 方案 | 形式 | 评价 |
|
|
263
|
+
|---|---|---|
|
|
264
|
+
| **U1** | `memory_note_pre` 加参数 `restore: [mem_id...]` ⇒ 把指定 id 的状态改回 `current` | 明确、可审计;但用户得先知道 id |
|
|
265
|
+
| **U2** | 面板上可点(白板/笔记页签对每条显示 status,点击切换) | 最直观;但有 UI 工作量,且属 S 层(界面层已封存到 3.1) |
|
|
266
|
+
| **U3** | 状态变更是**追加一条变更记录**而非原地改 ⇒ 天然可回滚 | 与 append-only 精神一致;但要注意 §3.1 已定"status 是字段不是新状态源" |
|
|
267
|
+
|
|
268
|
+
**倾向 U1**(成本最低、零 UI、立即可用),U2 留给 S 层。
|
|
269
|
+
|
|
270
|
+
> **纪律**:撤销必须**留痕**(谁在何时把它改回 `current`),否则又变成"静默改写"——那正是 §1 标本的成因。
|
|
271
|
+
|
|
272
|
+
### 8.4 与 M2 的关系(用户裁定:**一起做**)
|
|
273
|
+
|
|
274
|
+
| 项 | 形态 | 写盘? | 归属 |
|
|
275
|
+
|---|---|---|---|
|
|
276
|
+
| **M2 lint** | `lintWhiteboardPre(entries)` → 问题清单 | ❌ **绝不写** | 只读体检 |
|
|
277
|
+
| **G3 状态写入** | `memory_note_pre` 内的判定 + 写 `status` | ✅ 写(经正常写入通道) | 写入侧 |
|
|
278
|
+
|
|
279
|
+
**两者共用同一个"同主题判定"能力**,但**边界必须清晰**:
|
|
280
|
+
|
|
281
|
+
- **M2 只报告**(契约 §6 纪律,违反即把白板变成状态机)
|
|
282
|
+
- **G3 才写**,且**只写 `status` 字段,不新建状态源**(S10.4 合规:状态归记忆条目)
|
|
283
|
+
|
|
284
|
+
> ⚠️ **不要把 G3 的写入能力塞进 M2 的 lint**。M2 报"这条可能过时",G3 在**下次写入时**决定要不要标。**报告与写入分离**,这是两条纪律的交点。
|
|
285
|
+
|
|
286
|
+
**③④ 判据问题随之消解**:原 M2 卡在"③什么算概念/几次算反复、④什么算相关"。
|
|
287
|
+
⇒ 新方案下,**判据不再需要预先穷举**,改为:**主动触发(用户/模型显式说"这条取代那条")+ 写入时兜底比对**。
|
|
288
|
+
⇒ 故 §7-3 的悬置问题**已解除**,M2 的 ③④ 不再阻塞。
|
|
289
|
+
|
|
290
|
+
### 8.5 风险与约束(实施前必读)
|
|
291
|
+
|
|
292
|
+
1. **★ 语义引擎铁律**:语义臂依赖引擎(**JS 内置 = 默认形态;Python = 发烧友进阶项,两者可互换、严禁互相依赖**)。
|
|
293
|
+
⇒ G3 **必须 fail-soft**:语义引擎不可用时退回**词法臂**,**绝不因此不写状态、更不得让一个引擎的存在成为另一个生效的前提**。
|
|
294
|
+
2. **判定阈值要保守**:宁可漏判(回到现状)不可误判(标错作废)。建议**只在高置信度时自动标**,其余**只报告不标**。
|
|
295
|
+
3. **`memory_note_pre` 在热路径上**:新增语义检索有成本。需实测单次开销,必要时加**同主题缓存**或只在结论内容显著时触发。
|
|
296
|
+
4. **不新增状态源**(S10.4):`status` 是**已有字段**,G3 只是让它**第一次被写入**。任何"另建一份状态表"的做法都违规。
|
|
297
|
+
|
|
298
|
+
### 8.6 验收口径(能失败)
|
|
299
|
+
|
|
300
|
+
- [ ] 写一条新结论、显式声明取代旧条目 ⇒ 旧条目 `status` 变 `superseded`,**且 L0 版本指纹随之变化**。
|
|
301
|
+
- [ ] **误标可撤销**:走 U1 改回 `current`,且有留痕。
|
|
302
|
+
- [ ] **语义引擎关闭/不可用时**:退回词法臂,行为正常,**不报错、不跳过写入**。
|
|
303
|
+
- [ ] `memory_log_pre` 路径**零改动**(断言:日志写入不触发任何 status 写入)。
|
|
304
|
+
- [ ] M2 lint 跑完后**文件 mtime 不变**(只读纪律)。
|
|
305
|
+
- [ ] 每条都在 `tests/smoke/` 有套件,且**故意改坏实现时会红**。
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
*本文档为专项攻关纲领,执行细节落入 BATTLE-PLAN 的 G 系列。*
|