@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,254 @@
|
|
|
1
|
+
# ⑩-a / ⑩-b 规划(2026-09-19)
|
|
2
|
+
|
|
3
|
+
> **本文件是上下文压缩后的唯一恢复入口**——读完它即可恢复 ⑩ 的全部上下文,无需回溯对话。
|
|
4
|
+
> **术语校正**:用户口述「石壁」=**⑩-b**(「十B」的语音转写)。
|
|
5
|
+
> **⑩-b 的定义**=**记忆文件(`MEMORY.md`)侧的隐患**,含两件事:(i) 尚未引爆的 **M8 回写雷**;(ii) 排版与语义的耦合。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 0. 一句话定位(先看这张表)
|
|
10
|
+
|
|
11
|
+
| | **⑩-a** | **⑩-b** |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| **是什么** | **前端「记忆中枢」面板里看不懂** | **记忆文件侧的隐患**(回写雷 + 排版/语义耦合) |
|
|
14
|
+
| **用户本意** | ✅ **这就是 ⑩ 的原意**(2026-09-19 用户以面板截图澄清) | 后续深挖出来的 |
|
|
15
|
+
| **涉及语义引擎吗** | **不涉及**(已代码核实) | **涉及** |
|
|
16
|
+
| **涉及 `MEMORY.md` 吗** | **不涉及** | **涉及** |
|
|
17
|
+
| **今天的状态** | **待修**(用户指示先做) | **取证中**(两个只读子代理并行) |
|
|
18
|
+
|
|
19
|
+
**⑩ 的文档链**:
|
|
20
|
+
- 取证数据 → `R1-READABILITY-FORENSICS-20260919.md`
|
|
21
|
+
- 人话版 + 四选修法 → `ISSUE9-PURGE-AND-R1-PLAIN-20260919.md`
|
|
22
|
+
- **本文件 = 拆分为 ⑩-a / ⑩-b 后的执行规划**
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 1. ⑩-a · 前端面板可读性(**本项要做**)
|
|
27
|
+
|
|
28
|
+
### 1.1 现象(用户截图,2026-09-19)
|
|
29
|
+
前端「记忆中枢」→ 事实(Semantic)区,条目显示为乱码与噪声,**人看不懂**。
|
|
30
|
+
|
|
31
|
+
### 1.2 根因 = **数据脏,不是渲染差**(已实测)
|
|
32
|
+
|
|
33
|
+
喂该面板的是 `~/.dsh/memory/hub-pre/facts.json`。探针实测 **4 条中 3 条是坏的**:
|
|
34
|
+
|
|
35
|
+
| # | factId | 坏在哪 |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| 0 | `fact_pre_ac4920327df6601f25200d66e52df71f` | **22 个 U+FFFD**:`DSH ������ \| has three modes \| shadow …` |
|
|
38
|
+
| 1 | `fact_pre_a9380f5bca22011e33547a45542c61a3` | object 内嵌运行时信封:`Current DSH file policy: danger-full-access…` |
|
|
39
|
+
| 3 | `fact_pre_dda6cc1f36176f5ea000c6f681ea6818` | object 内嵌运行时信封:`Approval prompts are disabled in this session…` |
|
|
40
|
+
|
|
41
|
+
### 1.3 为什么脏 = **⑨ 只修了一半**(关键发现)
|
|
42
|
+
|
|
43
|
+
`lib/memory-hub-pre.js` 的 `crossFeed()` **两条通路不对称**:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
走 procedure(约 :152)→ stripRuntimeIntentPre(ep.intent) ✅ ⑨ 已修
|
|
47
|
+
走 fact (约 :166)→ subject: ep.intent.slice(0, 30) ❌ 完全没清洗
|
|
48
|
+
object: ep.unresolved[0].slice(0, 60) ❌ 直接切片
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
同理 `factCandidateFromRow()`(约 `:249-265`)**也不调**清洗器,只做 `String(row.subject || sourceIds[0])`。
|
|
52
|
+
⇒ **⑨ 修了「技能」那条路,「事实」这条路整套漏掉** —— 这是 `facts.json` 变脏的直接成因。
|
|
53
|
+
|
|
54
|
+
### 1.4 修复方案
|
|
55
|
+
|
|
56
|
+
| 步 | 动作 | 位置 |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| **a-1** | **清存量脏数据**(3 条) | `~/.dsh/memory/hub-pre/facts.json` |
|
|
59
|
+
| **a-2** | `crossFeed()` 的 **fact 分支**补清洗:`subject`/`object` 先过 `stripRuntimeIntentPre` | `lib/memory-hub-pre.js` 约 `:166-174` |
|
|
60
|
+
| **a-3** | `factCandidateFromRow()` 补清洗(`subject`/`predicate`/`object`) | 同文件约 `:249-265` |
|
|
61
|
+
| **a-4** | 新增 smoke 套件 + 变异演示 + 全量回归 | `tests/smoke/` · `artifacts/` |
|
|
62
|
+
|
|
63
|
+
**清洗器的选择**:复用 ⑨ 修好的 `stripRuntimeIntentPre()`(`lib/intent-clean-safe-pre.js`)。
|
|
64
|
+
它同时覆盖两类脏数据——**F3**(召回块/信封尾部标记)与 **F4**(`looksEncodingCorruptedPre`,U+FFFD ≥3)
|
|
65
|
+
⇒ 一条调用即可同时解决「信封污染」与「乱码」两种症状。
|
|
66
|
+
|
|
67
|
+
**⚠️ 清存量数据的坑(⑨ 已踩过,务必复用)**:
|
|
68
|
+
宿主**内存里持有副本**,`dispose()` 会**整份写回盘** ⇒ **直接编辑 json 会被回滚**。
|
|
69
|
+
⑨ 的解法是走宿主自己的 loopback 通路(`POST /api/dsh-auto-memory-pre/memory-hub`)。
|
|
70
|
+
|
|
71
|
+
### 1.4b ★ a-1 调研结论(2026-09-19 20:45 已查,**未动手**)
|
|
72
|
+
|
|
73
|
+
**事实一:fact store 没有「按 id 删除」的方法。**
|
|
74
|
+
`fact-store-pre.js:409-410` 导出的全集 = `upsert · supersede · get · query · conflictsList · pendingConflicts · resolveConflict · evidenceFor · revokeBySource · snapshot · restore · clear · dispose`
|
|
75
|
+
—— **没有 `remove` / `delete` / `revokeById`。**
|
|
76
|
+
|
|
77
|
+
**事实二:唯一的撤销通路是 `revokeBySource(sourceId)`(`:283-300`),且它按 provenance 反查**:
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
if (!Array.isArray(f.provenance) || !f.provenance.includes(sid)) continue
|
|
81
|
+
f.revoked = true; f.revokedAt = now; f.revokeReason = 'source-deleted'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
⇒ **只读不删**(注释明写「保留 provenance 与 revokedAt,只读不删(可审计、可追溯)」)。
|
|
85
|
+
|
|
86
|
+
**事实三:三条脏数据的 provenance 分别是** `mem_af41b679…`(记忆 id)、`epi_pre_66d51268…` / `epi_pre_010a543e…`(episode id)
|
|
87
|
+
⇒ 用 `revokeBySource` 清它们,**前提是先删掉那两个来源** —— 代价远大于清三条 fact。
|
|
88
|
+
|
|
89
|
+
**⇒ a-1 的三条候选路线(待用户拍板,勿自行选)**:
|
|
90
|
+
|
|
91
|
+
| | 做法 | 代价 | 评价 |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| **路 A** | 走 `storage-manage` 的 `delete`(`index.js:10476-10487`,级联 `factStore.revokeBySource`) | **要连带删掉那条记忆 / episode** | ❌ 副作用太大 |
|
|
94
|
+
| **路 B** | 新增 `revokeById(factId)`(按 id 直接撤销) | 动源码(新增方法 + 套件),但最小精准,**仍符合既有语义**(只读不删 + 留痕) | ⭕ 可选 |
|
|
95
|
+
| **路 C** | **不改数据,改行为**:让 `hubFlushTick` 的过滤条件**主动跳过脏 fact**(`subject`/`object` 命中清洗器判据即 skip) | **零数据改动**,脏条目留在盘上但**永远写不出去** | ✅ **倾向** |
|
|
96
|
+
|
|
97
|
+
**★ 更根本的判断**:⑩-a 的根因是「**fact 通路没清洗**」⇒ **先修 a-2/a-3,新脏数据即断源**。
|
|
98
|
+
**存量 3 条怎么处置,是独立的小决策**,不影响主线;且与 ⑨ 的取舍同源(**⑨ 时用户选的是「弃用不删」**)。
|
|
99
|
+
|
|
100
|
+
### 1.5 验收标准(可自动化)
|
|
101
|
+
1. `facts.json` 中 U+FFFD 计数 = 0
|
|
102
|
+
2. `facts.json` 中命中 `/Current DSH file policy|Approval prompts are disabled|Current runtime context|Retrieved memory ref/i` 的条数 = 0
|
|
103
|
+
3. 新套件断言:`crossFeed` 走 fact 时脏 intent **不落库**
|
|
104
|
+
4. 变异演示真红(把新加的清洗调用去掉 ⇒ 断言必须变红)
|
|
105
|
+
5. 全量回归 **0 失败**
|
|
106
|
+
|
|
107
|
+
### 1.6 风险与回退
|
|
108
|
+
- **风险:低**。不改注入路径、不改语义语料、不碰 `MEMORY.md`。
|
|
109
|
+
- **回退**:清洗器调用是**纯函数前置**,去掉即恢复原行为;数据侧有备份。
|
|
110
|
+
|
|
111
|
+
### 1.7 顺带记录(不在本次范围)
|
|
112
|
+
清洗后仍会看到 `XX | 有未决事项 | YY` 这类由 episode 自动派生的事实——**内容质量本身偏低**(它是「有未决事项」的机械模板,不是真的知识)。
|
|
113
|
+
**这是 ⑩-a 之后的独立话题**(可称 ⑩-a-2 「fact 质量」),需另立规划,不在本轮。
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 2. ⑩-b · 记忆文件侧的隐患(**本项只取证,不修**)
|
|
118
|
+
|
|
119
|
+
### 2.1 为什么「涉及语义」——三条管线的耦合(已代码核实)
|
|
120
|
+
|
|
121
|
+
`MEMORY.md` **不是纯文本**,它同时喂三条管线:
|
|
122
|
+
|
|
123
|
+
| # | 消费方 | 依据 |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| ① | **注入上下文**(整篇文本) | `lib/index.js:5498-5499` |
|
|
126
|
+
| ② | **L0 摘要抽取**(按 `<!-- memory:mem_<32hex> -->` 切条) | `lib/l0-extract-pre.js:34` |
|
|
127
|
+
| ③ | **语义语料**(锚点划字节区间 → `recordDigest`) | `lib/memory-anchor-pre.js:168/248`;复核在 `lib/m4-corpus-pre.js:107` |
|
|
128
|
+
|
|
129
|
+
**两条硬约束**:
|
|
130
|
+
- 文件级先比 `fileDigest`,不等则**跳过整个文件**(`m4-corpus-pre.js:96`,连逐条比对都不做);
|
|
131
|
+
- `sourceVersion` 随 `fileDigest` 变化 **+1**(`memory-anchor-pre.js:267`)⇒ 该文件**向量全部失效需重编码**。
|
|
132
|
+
|
|
133
|
+
**`memoryId` 是随机的**(`memory-anchor-pre.js:40` `newMemoryId()`)⇒ **就地改文件会换一批新 id**,
|
|
134
|
+
已积累的 `seen/read/cite` 证据、`supersededBy` 指针、白板锚点**全部对不上号**。
|
|
135
|
+
|
|
136
|
+
**正路**:sidecar 是**可重建的派生数据**(`note-status-pre.js:16` 明示)⇒ 改正文须配套走
|
|
137
|
+
`storage-manage-pre.js` 的 `repair` 重建 sidecar(**只重建 sidecar,不动正文**)。代价=向量重编码 + id 漂移。
|
|
138
|
+
**真正安全**:**追加式写入**(既有 `memory-writer` 事务路径),不改已有条目的字节布局。
|
|
139
|
+
**绝不可做**:改/删文件里的锚点标记——它是**切条唯一依据**,去掉后整篇退化为一个 legacy 块,`memoryId` 全丢。
|
|
140
|
+
|
|
141
|
+
### 2.2 ★★★ 尚未引爆的雷:**判断已被推翻 —— 它已经引爆过**(2026-09-19 子代理 A 取证 + 主代理独立复核)
|
|
142
|
+
|
|
143
|
+
> **⚠️ 本节原先写的是「实测尚未引爆」。该结论错误,已作废。**
|
|
144
|
+
> 错误根源:把「两份 `MEMORY.md` 里 `(M8 固化)` 计数为 0」当成了「没写过」的证据。
|
|
145
|
+
> **真相:写过了、而且是成功写入;后来被容量整理(compaction)移出正文、落进归档。**
|
|
146
|
+
|
|
147
|
+
**★ 铁证(主代理独立复核,非仅采信子代理)**:
|
|
148
|
+
|
|
149
|
+
| 证据 | 内容 |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `archive/notes-archived.md:493-495` | `## DSH ������(M8 固化)` / `- has three modes:shadow ֻ��¼ …` / `- 来源:记忆中枢治理固化(confidence=0.92)` |
|
|
152
|
+
| 同文件 `:519-521` / `:684-686` / `:3168-3170` | 另 3 段(`让我自己去试吧…` / `是这样的,我后台在改语义模型…` / `Approval prompts are disabled…`),**均带 `(M8 固化)`** |
|
|
153
|
+
| `MEMORY.md.bak-20260917-G2` | 正文里**曾有** `## Approval prompts are disabled(M8 固化)` ⇒ 证明**当时确实在正文** |
|
|
154
|
+
| 格式唯一性 | `(confidence=` 这一写法全仓只出现在 `lib/index.js:8981` ⇒ 这些段落**只能由本通路产生** |
|
|
155
|
+
| 锚点存在 | 每段都带 `<!-- memory:mem_<32hex> -->` ⇒ 走的是 `appendText` **正经事务**,不是事后手工拼 |
|
|
156
|
+
|
|
157
|
+
**⇒ 结论:`count: 0` 不是「没写」的证据。**
|
|
158
|
+
`index.js:8962` `if (hubFlushState.date !== today) { …count = 0 }` —— `count` 按**记忆日**清零,
|
|
159
|
+
当前 `date:2026-09-19 / count:0` 只表示「**今天还没写**」。
|
|
160
|
+
|
|
161
|
+
**危险本质(现已确认,不再是假设)**:**facts 侧是脏的(见 §1.2),而这条通路会把脏数据写进 `MEMORY.md`** ——
|
|
162
|
+
**从「面板难看」升级为「污染注入 + 污染语义语料」,且已实际发生。**
|
|
163
|
+
归档里那段 `## DSH ������(M8 固化)` 就是活证据。
|
|
164
|
+
|
|
165
|
+
### 2.3 ★ 子代理 A 的其余关键发现(含行号,可复核)
|
|
166
|
+
|
|
167
|
+
| # | 发现 | 依据 |
|
|
168
|
+
|---|---|---|
|
|
169
|
+
| 1 | **两条 tick 的开关门控是彻底的**(关掉不写),**但定时器无条件创建**、开关关掉后仍每 30min 空转;**`hubBootTimer` 未纳入 disposer** | `index.js:8918/8958`(门控)· `8992-8993`(无条件创建)· `8999`(只 clear 两个 interval) |
|
|
170
|
+
| 2 | **6 道过滤全是「结构性」,没有一道是「内容卫生」** —— 不查脏数据、不查长度、不查换行、不查信封 | `index.js:8970-8974` |
|
|
171
|
+
| 3 | **`confidence: null` 直接放行**(`typeof null === 'object'` 判假)⇒ facts.json 里 3 条 null **全部放行** | `index.js:8972` |
|
|
172
|
+
| 4 | **`ttl: 0` = 永不过期** ⇒ 4 条全放行 | `index.js:8971` + `fact-store-pre.js:60` |
|
|
173
|
+
| 5 | **换行未归一化** ⇒ 一条 fact 可**伪造 `## ` 标题**,并被 `compactLegacyLayer` 的分段正则当成独立段落搬运 | `index.js:8981` · `4796` `if (m = ln.match(/^##\s+(.+)$/))` |
|
|
174
|
+
| 6 | **失败静默**:`catch (_) {}` 吞异常(`:8987`),而 `hubFlushSave()`(`:8989`)**在 try 外无条件执行** ⇒ 失败也照写 flush-state | `index.js:8987` / `8989` |
|
|
175
|
+
| 7 | **`flushed` 与 `count` 不自洽**:`cur.includes(subj)` 分支只置标记、不 `count++`;且该标记**永久生效**;且判定用**子串**(短主语易误命中) | `index.js:8980` vs `8984-8985`;`8962` 只清 count 不清 flushed |
|
|
176
|
+
| 8 | **`flushed` 永不清理** ⇒ 实际语义是「**生命周期总量 8 条**」而非「每日 8 条」;**归档后永不重写**(单向) | 全仓无 `flushed = {}` / `delete` |
|
|
177
|
+
| 9 | **无重入保护**(`void hubFlushTick()` 无 in-flight 标志);文件不撕裂靠 docStore `_queue` 串行,但 **flush-state.json 是裸 `writeFileSync`,无锁无 tmp+rename** | `index.js:8993` · `8895` · `memory-writer-pre.js:345-352/506` |
|
|
178
|
+
| 10 | **`hubFlushSave` 写失败被静默吞** ⇒ 重启后 `flushed` 回退 ⇒ **已写过的 fact 会被再写一遍**(正文出现两个同名 `(M8 固化)` 段落) | `index.js:8895` `catch (_) {}` |
|
|
179
|
+
| 11 | **可观察性缺失**:成功有 `diag`(`:8986`),**失败零留痕**(无 diag、无 degrade 台账,对照 `:5853` note-status 路径**有** `_degradePre.record`);`overview()` **不含 flush 字段** ⇒ 面板看不到「写了但没成功」 | `index.js:8986/8987` · `memory-hub-pre.js:192-220` |
|
|
180
|
+
|
|
181
|
+
### 2.4 待查清单(子代理 B 仍在运行)
|
|
182
|
+
|
|
183
|
+
**子代理 B —— `MEMORY.md` 全部写入者普查**(`88b6427e-5393-42b7-bed3-ee46c41e8ce6`):完整清单 → 是否走事务 → `memoryId` 命运 → sidecar 与 digest → 风险面 → 现有防线。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### 2.5 ★★★ ⑩-b 完整取证报告(2026-09-19 已完工)
|
|
188
|
+
|
|
189
|
+
> **`docs/internal/ISSUE10B-FORENSICS-20260919.md`** ← **⑩-b 的唯一权威文档,压缩后读它**
|
|
190
|
+
|
|
191
|
+
**两份只读子代理普查 + 主代理逐条复核的合并成果**,含:
|
|
192
|
+
|
|
193
|
+
| 节 | 内容 |
|
|
194
|
+
|---|---|
|
|
195
|
+
| §0 | 一句话结论:**20 条写入通路 × 3 条消费管线,中间没有任何联合把关** |
|
|
196
|
+
| §1 | 三条消费管线(注入 / L0 / 语料)+ 语料的两级静默丢弃 |
|
|
197
|
+
| §2 | **20 条写入者全景表** + 清洗门只接 5 处 + **全自动无人值守的只有 3 条** |
|
|
198
|
+
| §3 | 三个致命结构问题:`stripAnchorLines` 承诺不成立 · `reuse` 是死代码 · `sanitizeReservedSyntax` 去功能化 |
|
|
199
|
+
| §4 | M8 回写通路:**已引爆的物证** + 六道过滤 + 五个失败模式 |
|
|
200
|
+
| §5 | **主代理对子代理的三处纠正**(含「默认裸写」对用户本机不成立) |
|
|
201
|
+
| §6 | 风险排序 + **「自我放大回路」** |
|
|
202
|
+
| **§8** | **★ 修复方案 T0/T1/T2/T3 四层 + 执行顺序 + 验收标准 + 风险回退** |
|
|
203
|
+
|
|
204
|
+
**★ 最重要的一条新增认知(§6)**:
|
|
205
|
+
```
|
|
206
|
+
记忆文件字节 → m4-corpus-pre.js:118 取 text → index.js:8943 作 fact.subject
|
|
207
|
+
↓
|
|
208
|
+
hubFlushTick:8982 写回 MEMORY.md
|
|
209
|
+
↓
|
|
210
|
+
(若脏)再次成为语料来源 → 再固化 → 再写回
|
|
211
|
+
```
|
|
212
|
+
⇒ **脏数据不只是「落盘」,它会自己繁殖。**
|
|
213
|
+
|
|
214
|
+
**★ 关键洞察(§8.1)**:**⑩-a 的修法就是 ⑩-b 的主要止血手段** ——
|
|
215
|
+
`crossFeed` 的 fact 分支未清洗,既是 §1.2(面板乱码)的成因,也是 M8 回写脏数据的源头。
|
|
216
|
+
**给 fact 通路补清洗器,同时解决 ⑩-a 与 ⑩-b 的脏源。**
|
|
217
|
+
|
|
218
|
+
**★ 诚实评估紧急度(§8.0)**:急性事故已发生完毕(4 条已写入并归档),**没有持续流血**;
|
|
219
|
+
但 `count` 每日清零、`flushed` 永不清零 ⇒ **每个记忆日仍有最多 8 次脏写入机会**,且脏源持续产生。
|
|
220
|
+
⇒ **中高优先,应在进入前端前修完**(与用户既定节奏一致)。
|
|
221
|
+
|
|
222
|
+
### 2.4 取证完成后的流程(用户指定)
|
|
223
|
+
1. 把「它是什么、怎么干、会造成什么隐患」讲清楚 → **用户看**
|
|
224
|
+
2. 用户与 agent 一起定修法 → **修复方案再落一次盘**
|
|
225
|
+
3. 用户压缩上下文 → **agent 一次修完**
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 3. 执行序(用户 2026-09-19 指定)
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
[1] 本规划落盘 ← 本文件
|
|
233
|
+
[2] ⑩-a 修复(面板清晰可懂) ← 先做
|
|
234
|
+
[3] ⑩-b 全量取证(子代理,只读) ← 已并行启动
|
|
235
|
+
[4] 向用户讲清 ⑩-b 的隐患 → 用户拍板修法 → 修法落盘
|
|
236
|
+
[5] 用户压缩上下文 → agent 修完 ⑩-b
|
|
237
|
+
[6] 走到前端方向
|
|
238
|
+
[7] 前端做完 → GLM 全量审核 + 白皮书
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**注意**:⑩-a 与 ⑩-b **不互相阻塞**:⑩-a 不碰 `MEMORY.md`、不碰语义语料。
|
|
242
|
+
但 ⑩-a 的清洗器修复**会降低 ⑩-b 的风险**(脏 fact 不再新增)。
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 4. 与最终方向的关系(用户 2026-09-19 补充)
|
|
247
|
+
|
|
248
|
+
⑩-b 不是孤例,而是**一类系统性风险的一次样本**:本插件的「记忆」不是普通文件,
|
|
249
|
+
而是**注入面 + 检索面 + 语义面共用的同一份字节**。任何一处写入都要同时满足三套约束,
|
|
250
|
+
而**历史实现是分批长出来的**——于是「一处漏清洗」「一处绕过事务」这类雷会零散地留着。
|
|
251
|
+
|
|
252
|
+
⇒ 这正是**前端做完后必须做「GLM 全量审核 + 白皮书」**的原因:
|
|
253
|
+
**逐条修只能清掉已知的雷,全量审核才能把「还有多少雷、都分布在哪一类通路」讲清楚**,
|
|
254
|
+
白皮书则是把这套「三面共用一份字节」的约束**显式成文**,让后续任何写入者都不再靠口口相传。
|