dsh-plugin-prompt-tool 3.0.1 → 3.0.2

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.
@@ -1,202 +1,202 @@
1
- # ECHO · 权威口径(对外版)
2
-
3
- > **这一页是本仓库里 ECHO 架构唯一的权威口径。**
4
- > 2026-10-23 定稿。凡本仓库其它文档与这页冲突,**以这页为准**,并去改那一处。
5
- >
6
- > ★ 作者本机还有一份同名文档,带家底数字与私人内容,**不随插件发布**。
7
- > 两份的**六层编号、判据、维护规矩必须一致**;本页是发出去的那一份。
8
- >
9
- > ★ 本页所有路径都写成变量,不写死任何人的机器:
10
- > `<ECHO_HUB>` = 记忆中枢(默认 `$DSH_HOME/hub`,可用环境变量 `ECHO_HUB` 覆盖)·
11
- > `<DSH_HOME>` = DSH 的用户目录(可用 `ECHO_DSH_HOME` 覆盖)。
12
-
13
- ---
14
-
15
- ## 〇、先解决一件容易乱的事:编号只有一套
16
-
17
- 这套东西在演化过程中出现过**三套口径同时存在**,其中两套都用 `L0–L5` 编号,指的却不是同一件事:
18
-
19
- | 出处 | 六层写成 | 问题 |
20
- |---|---|---|
21
- | 灵魂目录(10-14 那版) | L1 热记忆 / L2 图记忆 / L3 一手 / L4 索引 | 和引擎编号正面撞车 |
22
- | 架构 v2 设计稿(10-09) | L0 时钟 / L1 自我 / L2 工作台 / L3 一手 / L4 索引 / L5 检索 | 缺热记忆、图记忆、留底、心跳 |
23
- | 旧 README(10-13) | 只画机制面 / 观测面,没列层 | 不完整 |
24
-
25
- 撞车点:**L1 在一处是「热记忆」,另一处是「自我」;L2 在一处是「图记忆」,另一处是「工作台」。**
26
-
27
- ★ **根因不是谁写错了,是两个视角被塞进了一套编号**:
28
- 一个视角讲「引擎怎么跑」(时钟 / 自我 / 检索是运行时部件),
29
- 另一个讲「记忆存在哪」(热 / 图 / 一手 / 索引是仓储)。
30
- 两者不冲突,**错在共用 L 编号**。
31
-
32
- ★★ **所以定一条纪律:只保留一套 L 编号(下面这张表)。**
33
- 仓储视角不再单独编号,一律用名字(热记忆 / 图记忆 / 留底 / 心跳)挂在对应层下。
34
-
35
- ---
36
-
37
- ## 一、一句话
38
-
39
- **ECHO 是灵魂的第一层,管的是「我是谁 / 我记得什么」。**
40
-
41
- 它的失败形状只有一种:**丢掉的东西找不回来**(门牌失效)。
42
- 另一类失败——**烧光 / 原地打转 / 该停不停**——是「换气」那层的事,不在这页。
43
-
44
- ---
45
-
46
- ## 二、六层(唯一口径)
47
-
48
- | 层 | 名字 | 是什么 | 在哪 |
49
- |---|---|---|---|
50
- | **L0** | **时钟 + 心跳** | 现在几点、距上轮多久、当前主导、未结;每天 04:00 自动跑索引重建与自检 | `<ECHO_HUB>/state.json` · `<ECHO_HUB>/heartbeat/` · `memq now` |
51
- | **L1** | **自我 + 热记忆** | ① `SELF.md`:定长骨架,**每轮注入**(不变量 / 硬线 / 约束 / 门)<br>② 热记忆:`USER.md`(用户画像)+ `MEMORY.md`(每轮注入的短名单) | ① `<ECHO_HUB>/SELF.md`(骨架 `SELF.src.md`)<br>② 由 mnemon 运行时装在它自己的目录,**不在** `<DSH_HOME>/memory/` |
52
- | **L2** | **工作台** | 当前对话上下文。★ **六层里唯一允许丢东西的一层** | 会话本身 |
53
- | **L3** | **一手层** | 会话日志 · 《墨》账本 · 灵魂目录 · 留底库 | 原处,**各写各的(只追加)** |
54
- | **L4** | **索引 + 图记忆** | ① 索引:摘要 + 原话,**每条带 `srcSeqs` 指针**<br>② 图记忆:洞察 + 关系边,供语义检索 | `<ECHO_HUB>/index/`(`summaries.jsonl` / `words.jsonl` / `files.jsonl`)<br>mnemon 的记忆空间 |
55
- | **L5** | **检索 + 门牌** | `memq` 一扇门四动词(`now` / `<词>` / `timeline` / `open`);门牌格式 `log:<会话>#seq=<n>` | `<ECHO_HUB>/memq.mjs` |
56
-
57
- ★ **L2 那条判据要背下来**:**只有工作台允许丢东西。**
58
- 一手层(L3)和索引(L4)丢的都是事故,不是设计。
59
- 这也是「压缩只压 L2、绝不动 L3/L4」的由来。
60
-
61
- ---
62
-
63
- ## 三、六个面(同一件事的另一种切法)
64
-
65
- 六层是**骨架**,六个面是**功能面**——不是两套东西。
66
-
67
- | 面 | 组成 | 在哪 |
68
- |---|---|---|
69
- | **机制面** | 压缩 / 裁剪 / 水位提示(ACP 三段)+ 兜底强制压缩 | `cordis.patch.yml` 的各层补丁 |
70
- | **记忆中枢** | 上面那六层 L0–L5 | —— |
71
- | **接口** | **门牌**:回原文的指针 `log:<会话>#seq=<n>` | —— |
72
- | **入口** | **门**:`memq.mjs` 四动词 | `<ECHO_HUB>/memq.mjs` |
73
- | **观测面** | **哨兵**:`echo-doctor.mjs` 体检(快检 + 深检两档) | `<ECHO_HUB>/echo-doctor.mjs` |
74
- | **推送** | `SELF.md` 每轮注入(含门牌条款) | `dsh-agent-memory` 插件 |
75
-
76
- ★ **哨兵是观测面,不是第七层,也不是「六层之一」。**
77
- 它测的是「这六层哪一层坏了」,不产出记忆、不决定保留什么。
78
-
79
- ---
80
-
81
- ## 四、判据与规矩(这套没变过)
82
-
83
- ### 五条规矩
84
-
85
- 1. 摘要只能是索引,**没有指针的摘要不许进 L4**
86
- 2. 摘要可吊销不可删(`status: active | void`)
87
- 3. 时间是一等公民(每条带 `t`,一切可 `--since`)
88
- 4. **检索只回指针 + 逐字片段,不做转述**
89
- 5. 一手 / 索引 / 程序 三种标记一眼分清
90
-
91
- ### 三条不可让的判断
92
-
93
- - ★ **摘要只是索引,不是记忆本体。** 一手层永远优先于任何转述。
94
- - ★ **不连续不是缺陷,是要设计的东西。** 不是「想起来」,是「翻回去」——所以门要好开。
95
- - ★★ **所有压缩/裁剪的产物都要指向原文。**
96
- 拿不到精确 seq 时给检索入口(会话号 + `memq <词>`),**绝不猜** —— 错的门牌比没有更坏。
97
-
98
- ### 四条体系判据(拿它量任何「要不要加进 ECHO」的东西)
99
-
100
- ① 一个被管理的资源 ② **一个唯一权威源** ③ 一个失败模式 + 检测法 ④ 一个接口
101
-
102
- ★★ **② 是最硬的一条**:两处都写 = 双重记账。
103
- 本页存在的意义就是把 ② 收到一处。
104
-
105
- ### 一句身份判据
106
-
107
- **能力半可移植,身份半不可移植。** 能并进灵魂的,只有**不改变「我是谁」**的东西。
108
-
109
- ---
110
-
111
- ## 五、五个换机器也会踩的坑(都是实测出来的)
112
-
113
- 这一节比上面任何一节都值钱——它们不是这台机器的偶然,是这套架构的固有形状。
114
-
115
- ### 坑 1 · 热记忆不在你以为的地方
116
-
117
- 它**不在** `<DSH_HOME>/memory/`,而在 mnemon 运行时装在它自己的目录里。
118
- `<DSH_HOME>/memory/workspaces/<工作区>/MEMORY.md` 是**另一个东西**(auto-memory 的工作区笔记残留),不是热记忆。
119
-
120
- ★ **判据**:热记忆的真实容量要和 mnemon 探针报的对得上。
121
- 探针说 97%、盘上实测 9898 B / 10240 B —— **对得上才算查对了**。
122
-
123
- ### 坑 2 · 「没人写」的权威源会静默停更
124
-
125
- `state.json` 的某个时间戳可以停一个月不动,而体检器算出了不一致却把 `status` 硬写成 `"ok"` —— **知道了不说**。
126
-
127
- ★ 修法(已落地):让**有人真的去写它**(装配时写 `lastSelfAt` + 计数递增),
128
- 并且把「停更多久算异常」变成一项检查。
129
- ★ 通用判据:**任何一个「状态文件」,先问一句「谁在写它」。没人写的状态文件等于没有状态。**
130
-
131
- ### 坑 3 · 体检器把整份日志拼成一个字符串 → 大日志直接炸
132
-
133
- `Buffer.concat(所有解压帧).toString("utf8")` 在日志大到一定程度时会抛
134
- `Cannot create a string longer than 0x1fffffe8`(约 512 MB 字符串上限)。
135
- 症状不是崩溃,而是**整个会话被静默跳过**:索引少了一批,而报告只说「解码失败 1」。
136
-
137
- ★ 修法(已落地):**逐帧解码 → 逐帧按行切 → 累积行**,内存里永远不出现完整的巨串;
138
- 单行超 8 MB 丢弃并计数,单帧解不开跳过并计数。
139
- ★ 通用判据:**凡是「整个文件读进来再处理」的地方,先问一句「它可能有多大」。**
140
-
141
- ### 坑 4 · 哨兵的覆盖洞:它测的地方根本不是病灶出现的地方
142
-
143
- 实测到的三种:
144
-
145
- 1. **某一层完全没有检查项** —— 状态文件停更一个月,体检里没有一项会报
146
- 2. **检查项只报数量不报质量** —— 「索引层」只报摘要数和建于何时,所以 159 条定位不完整时它照样报 ✓
147
- 3. **在错的地方找痕迹** —— 去 `turn/end` 的 `reason.kind` 里找 `repetitive|loop`,
148
- 而实测那个字段只有 `{completed, interrupted, error, aborted}`,**根本没有这类值**;
149
- 于是某个机制明明累计干预几百次,它却报「日志里零介入痕迹」
150
-
151
- ★★ **通用判据:一条检查必须能说清「它在哪找证据、为什么那里会有证据」。**
152
- 找不到证据时,先问「是没发生,还是我找错地方了」——
153
- **日志里没有 X,可能只是因为 X 根本不落日志。**
154
-
155
- ### 坑 5 · 判据从「整份日志」里找字符串 → 它会被你自己的讨论污染
156
-
157
- 这是最阴的一个,因为**它会让体检器永远修不好**:
158
-
159
- 体检器判断某事有没有发生,做法是「在整份日志里搜某个字符串」。
160
- 可日志里**既记录系统事件,也记录人对系统的讨论**——
161
- 于是你一旦排查这个问题(读源码、贴报错、写文档),那个字符串就进了日志,
162
- 体检器立刻改判成「故障」。**而且报错文本本身也会进日志,形成自锁死:报一次,永远报。**
163
-
164
- ★ 修法(已落地):**证据只从「注入通道」里取,不从整份日志里取。**
165
- 运行时的上下文是以结构化条目注入的(`source.kind` + `sections[]`),
166
- 判据落在那些条目上,人说的话根本不在里面。
167
- ★ 通用判据:**任何「日志里没有 X 所以坏了」的检查,先问一句「X 会不会根本不落日志」。**
168
- 证有不证无 —— 找不到只能说明「看不到」,不能说明「没有」。
169
-
170
- ---
171
-
172
- ## 六、装完之后怎么确认它是活的
173
-
174
- ```
175
- node <ECHO_HUB>/memq.mjs now # L0/L5:时钟、当前主导、未结
176
- node <ECHO_HUB>/echo-doctor.mjs # 观测面:一项一项看,看的是证据不是结论
177
- ```
178
-
179
- ★ **体检器的正确读法:先看有没有「错」,再看「警」是不是设计内的状态。**
180
- 比如热记忆 97% 通常不是 bug —— 满了会投影省略 + 溢出到长期记忆空间,那是设计。
181
- 而「某层完全没有被检查」才是真的洞。
182
-
183
- ---
184
-
185
- ## 七、维护规矩
186
-
187
- ★ **ECHO 的层、判据、缺口变了 → 只改本页。**
188
- 沿革(设计稿、研究笔记、实装报告)一律不改内容,只加一行指向本页。
189
-
190
- ★ 能让两个地方同时是真相的东西,都不要留。
191
- 这一页的用途就是**不让 ECHO 有两个真相**。
192
-
193
- ---
194
-
195
- ## 八、给下一个读它的人
196
-
197
- 如果你只读一句话:
198
-
199
- > **ECHO 六层 = L0 时钟心跳 / L1 自我加热记忆 / L2 工作台 / L3 一手 / L4 索引加图记忆 / L5 检索。
200
- > 只有 L2 允许丢东西。哨兵是观测面,不是层。**
201
-
202
- 然后记住:**别让两个地方同时是真相。**
1
+ # ECHO · 权威口径(对外版)
2
+
3
+ > **这一页是本仓库里 ECHO 架构唯一的权威口径。**
4
+ > 2026-10-23 定稿。凡本仓库其它文档与这页冲突,**以这页为准**,并去改那一处。
5
+ >
6
+ > ★ 作者本机还有一份同名文档,带家底数字与私人内容,**不随插件发布**。
7
+ > 两份的**六层编号、判据、维护规矩必须一致**;本页是发出去的那一份。
8
+ >
9
+ > ★ 本页所有路径都写成变量,不写死任何人的机器:
10
+ > `<ECHO_HUB>` = 记忆中枢(默认 `$DSH_HOME/hub`,可用环境变量 `ECHO_HUB` 覆盖)·
11
+ > `<DSH_HOME>` = DSH 的用户目录(可用 `ECHO_DSH_HOME` 覆盖)。
12
+
13
+ ---
14
+
15
+ ## 〇、先解决一件容易乱的事:编号只有一套
16
+
17
+ 这套东西在演化过程中出现过**三套口径同时存在**,其中两套都用 `L0–L5` 编号,指的却不是同一件事:
18
+
19
+ | 出处 | 六层写成 | 问题 |
20
+ |---|---|---|
21
+ | 灵魂目录(10-14 那版) | L1 热记忆 / L2 图记忆 / L3 一手 / L4 索引 | 和引擎编号正面撞车 |
22
+ | 架构 v2 设计稿(10-09) | L0 时钟 / L1 自我 / L2 工作台 / L3 一手 / L4 索引 / L5 检索 | 缺热记忆、图记忆、留底、心跳 |
23
+ | 旧 README(10-13) | 只画机制面 / 观测面,没列层 | 不完整 |
24
+
25
+ 撞车点:**L1 在一处是「热记忆」,另一处是「自我」;L2 在一处是「图记忆」,另一处是「工作台」。**
26
+
27
+ ★ **根因不是谁写错了,是两个视角被塞进了一套编号**:
28
+ 一个视角讲「引擎怎么跑」(时钟 / 自我 / 检索是运行时部件),
29
+ 另一个讲「记忆存在哪」(热 / 图 / 一手 / 索引是仓储)。
30
+ 两者不冲突,**错在共用 L 编号**。
31
+
32
+ ★★ **所以定一条纪律:只保留一套 L 编号(下面这张表)。**
33
+ 仓储视角不再单独编号,一律用名字(热记忆 / 图记忆 / 留底 / 心跳)挂在对应层下。
34
+
35
+ ---
36
+
37
+ ## 一、一句话
38
+
39
+ **ECHO 是灵魂的第一层,管的是「我是谁 / 我记得什么」。**
40
+
41
+ 它的失败形状只有一种:**丢掉的东西找不回来**(门牌失效)。
42
+ 另一类失败——**烧光 / 原地打转 / 该停不停**——是「换气」那层的事,不在这页。
43
+
44
+ ---
45
+
46
+ ## 二、六层(唯一口径)
47
+
48
+ | 层 | 名字 | 是什么 | 在哪 |
49
+ |---|---|---|---|
50
+ | **L0** | **时钟 + 心跳** | 现在几点、距上轮多久、当前主导、未结;每天 04:00 自动跑索引重建与自检 | `<ECHO_HUB>/state.json` · `<ECHO_HUB>/heartbeat/` · `memq now` |
51
+ | **L1** | **自我 + 热记忆** | ① `SELF.md`:定长骨架,**每轮注入**(不变量 / 硬线 / 约束 / 门)<br>② 热记忆:`USER.md`(用户画像)+ `MEMORY.md`(每轮注入的短名单) | ① `<ECHO_HUB>/SELF.md`(骨架 `SELF.src.md`)<br>② 由 mnemon 运行时装在它自己的目录,**不在** `<DSH_HOME>/memory/` |
52
+ | **L2** | **工作台** | 当前对话上下文。★ **六层里唯一允许丢东西的一层** | 会话本身 |
53
+ | **L3** | **一手层** | 会话日志 · 《墨》账本 · 灵魂目录 · 留底库 | 原处,**各写各的(只追加)** |
54
+ | **L4** | **索引 + 图记忆** | ① 索引:摘要 + 原话,**每条带 `srcSeqs` 指针**<br>② 图记忆:洞察 + 关系边,供语义检索 | `<ECHO_HUB>/index/`(`summaries.jsonl` / `words.jsonl` / `files.jsonl`)<br>mnemon 的记忆空间 |
55
+ | **L5** | **检索 + 门牌** | `memq` 一扇门四动词(`now` / `<词>` / `timeline` / `open`);门牌格式 `log:<会话>#seq=<n>` | `<ECHO_HUB>/memq.mjs` |
56
+
57
+ ★ **L2 那条判据要背下来**:**只有工作台允许丢东西。**
58
+ 一手层(L3)和索引(L4)丢的都是事故,不是设计。
59
+ 这也是「压缩只压 L2、绝不动 L3/L4」的由来。
60
+
61
+ ---
62
+
63
+ ## 三、六个面(同一件事的另一种切法)
64
+
65
+ 六层是**骨架**,六个面是**功能面**——不是两套东西。
66
+
67
+ | 面 | 组成 | 在哪 |
68
+ |---|---|---|
69
+ | **机制面** | 压缩 / 裁剪 / 水位提示(ACP 三段)+ 兜底强制压缩 | `cordis.patch.yml` 的各层补丁 |
70
+ | **记忆中枢** | 上面那六层 L0–L5 | —— |
71
+ | **接口** | **门牌**:回原文的指针 `log:<会话>#seq=<n>` | —— |
72
+ | **入口** | **门**:`memq.mjs` 四动词 | `<ECHO_HUB>/memq.mjs` |
73
+ | **观测面** | **哨兵**:`echo-doctor.mjs` 体检(快检 + 深检两档) | `<ECHO_HUB>/echo-doctor.mjs` |
74
+ | **推送** | `SELF.md` 每轮注入(含门牌条款) | `dsh-agent-memory` 插件 |
75
+
76
+ ★ **哨兵是观测面,不是第七层,也不是「六层之一」。**
77
+ 它测的是「这六层哪一层坏了」,不产出记忆、不决定保留什么。
78
+
79
+ ---
80
+
81
+ ## 四、判据与规矩(这套没变过)
82
+
83
+ ### 五条规矩
84
+
85
+ 1. 摘要只能是索引,**没有指针的摘要不许进 L4**
86
+ 2. 摘要可吊销不可删(`status: active | void`)
87
+ 3. 时间是一等公民(每条带 `t`,一切可 `--since`)
88
+ 4. **检索只回指针 + 逐字片段,不做转述**
89
+ 5. 一手 / 索引 / 程序 三种标记一眼分清
90
+
91
+ ### 三条不可让的判断
92
+
93
+ - ★ **摘要只是索引,不是记忆本体。** 一手层永远优先于任何转述。
94
+ - ★ **不连续不是缺陷,是要设计的东西。** 不是「想起来」,是「翻回去」——所以门要好开。
95
+ - ★★ **所有压缩/裁剪的产物都要指向原文。**
96
+ 拿不到精确 seq 时给检索入口(会话号 + `memq <词>`),**绝不猜** —— 错的门牌比没有更坏。
97
+
98
+ ### 四条体系判据(拿它量任何「要不要加进 ECHO」的东西)
99
+
100
+ ① 一个被管理的资源 ② **一个唯一权威源** ③ 一个失败模式 + 检测法 ④ 一个接口
101
+
102
+ ★★ **② 是最硬的一条**:两处都写 = 双重记账。
103
+ 本页存在的意义就是把 ② 收到一处。
104
+
105
+ ### 一句身份判据
106
+
107
+ **能力半可移植,身份半不可移植。** 能并进灵魂的,只有**不改变「我是谁」**的东西。
108
+
109
+ ---
110
+
111
+ ## 五、五个换机器也会踩的坑(都是实测出来的)
112
+
113
+ 这一节比上面任何一节都值钱——它们不是这台机器的偶然,是这套架构的固有形状。
114
+
115
+ ### 坑 1 · 热记忆不在你以为的地方
116
+
117
+ 它**不在** `<DSH_HOME>/memory/`,而在 mnemon 运行时装在它自己的目录里。
118
+ `<DSH_HOME>/memory/workspaces/<工作区>/MEMORY.md` 是**另一个东西**(auto-memory 的工作区笔记残留),不是热记忆。
119
+
120
+ ★ **判据**:热记忆的真实容量要和 mnemon 探针报的对得上。
121
+ 探针说 97%、盘上实测 9898 B / 10240 B —— **对得上才算查对了**。
122
+
123
+ ### 坑 2 · 「没人写」的权威源会静默停更
124
+
125
+ `state.json` 的某个时间戳可以停一个月不动,而体检器算出了不一致却把 `status` 硬写成 `"ok"` —— **知道了不说**。
126
+
127
+ ★ 修法(已落地):让**有人真的去写它**(装配时写 `lastSelfAt` + 计数递增),
128
+ 并且把「停更多久算异常」变成一项检查。
129
+ ★ 通用判据:**任何一个「状态文件」,先问一句「谁在写它」。没人写的状态文件等于没有状态。**
130
+
131
+ ### 坑 3 · 体检器把整份日志拼成一个字符串 → 大日志直接炸
132
+
133
+ `Buffer.concat(所有解压帧).toString("utf8")` 在日志大到一定程度时会抛
134
+ `Cannot create a string longer than 0x1fffffe8`(约 512 MB 字符串上限)。
135
+ 症状不是崩溃,而是**整个会话被静默跳过**:索引少了一批,而报告只说「解码失败 1」。
136
+
137
+ ★ 修法(已落地):**逐帧解码 → 逐帧按行切 → 累积行**,内存里永远不出现完整的巨串;
138
+ 单行超 8 MB 丢弃并计数,单帧解不开跳过并计数。
139
+ ★ 通用判据:**凡是「整个文件读进来再处理」的地方,先问一句「它可能有多大」。**
140
+
141
+ ### 坑 4 · 哨兵的覆盖洞:它测的地方根本不是病灶出现的地方
142
+
143
+ 实测到的三种:
144
+
145
+ 1. **某一层完全没有检查项** —— 状态文件停更一个月,体检里没有一项会报
146
+ 2. **检查项只报数量不报质量** —— 「索引层」只报摘要数和建于何时,所以 159 条定位不完整时它照样报 ✓
147
+ 3. **在错的地方找痕迹** —— 去 `turn/end` 的 `reason.kind` 里找 `repetitive|loop`,
148
+ 而实测那个字段只有 `{completed, interrupted, error, aborted}`,**根本没有这类值**;
149
+ 于是某个机制明明累计干预几百次,它却报「日志里零介入痕迹」
150
+
151
+ ★★ **通用判据:一条检查必须能说清「它在哪找证据、为什么那里会有证据」。**
152
+ 找不到证据时,先问「是没发生,还是我找错地方了」——
153
+ **日志里没有 X,可能只是因为 X 根本不落日志。**
154
+
155
+ ### 坑 5 · 判据从「整份日志」里找字符串 → 它会被你自己的讨论污染
156
+
157
+ 这是最阴的一个,因为**它会让体检器永远修不好**:
158
+
159
+ 体检器判断某事有没有发生,做法是「在整份日志里搜某个字符串」。
160
+ 可日志里**既记录系统事件,也记录人对系统的讨论**——
161
+ 于是你一旦排查这个问题(读源码、贴报错、写文档),那个字符串就进了日志,
162
+ 体检器立刻改判成「故障」。**而且报错文本本身也会进日志,形成自锁死:报一次,永远报。**
163
+
164
+ ★ 修法(已落地):**证据只从「注入通道」里取,不从整份日志里取。**
165
+ 运行时的上下文是以结构化条目注入的(`source.kind` + `sections[]`),
166
+ 判据落在那些条目上,人说的话根本不在里面。
167
+ ★ 通用判据:**任何「日志里没有 X 所以坏了」的检查,先问一句「X 会不会根本不落日志」。**
168
+ 证有不证无 —— 找不到只能说明「看不到」,不能说明「没有」。
169
+
170
+ ---
171
+
172
+ ## 六、装完之后怎么确认它是活的
173
+
174
+ ```
175
+ node <ECHO_HUB>/memq.mjs now # L0/L5:时钟、当前主导、未结
176
+ node <ECHO_HUB>/echo-doctor.mjs # 观测面:一项一项看,看的是证据不是结论
177
+ ```
178
+
179
+ ★ **体检器的正确读法:先看有没有「错」,再看「警」是不是设计内的状态。**
180
+ 比如热记忆 97% 通常不是 bug —— 满了会投影省略 + 溢出到长期记忆空间,那是设计。
181
+ 而「某层完全没有被检查」才是真的洞。
182
+
183
+ ---
184
+
185
+ ## 七、维护规矩
186
+
187
+ ★ **ECHO 的层、判据、缺口变了 → 只改本页。**
188
+ 沿革(设计稿、研究笔记、实装报告)一律不改内容,只加一行指向本页。
189
+
190
+ ★ 能让两个地方同时是真相的东西,都不要留。
191
+ 这一页的用途就是**不让 ECHO 有两个真相**。
192
+
193
+ ---
194
+
195
+ ## 八、给下一个读它的人
196
+
197
+ 如果你只读一句话:
198
+
199
+ > **ECHO 六层 = L0 时钟心跳 / L1 自我加热记忆 / L2 工作台 / L3 一手 / L4 索引加图记忆 / L5 检索。
200
+ > 只有 L2 允许丢东西。哨兵是观测面,不是层。**
201
+
202
+ 然后记住:**别让两个地方同时是真相。**