dsh-plugin-prompt-tool 3.0.1 → 3.1.0
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 +17 -1
- package/engine/actions/catalog.mjs +2 -1
- package/engine/actions/index.mjs +5 -3
- package/engine/actions/shared.mjs +26 -12
- package/engine/actions/tool-visibility.mjs +31 -14
- package/engine/compositions/source/local/context-provenance.yml +9 -0
- package/engine/compositions/source/local/generation-recovery.yml +10 -0
- package/engine/compositions/source/local/retrieval.yml +7 -0
- package/engine/compositions/source/local/soul-ledger.yml +3 -0
- package/engine/compositions/source/local/soul-maintenance.yml +9 -0
- package/engine/conditions/examples.mjs +1 -0
- package/engine/conditions/index.mjs +7 -0
- package/engine/conditions/manifest.mjs +28 -0
- package/engine/context-idle-compaction.mjs +58 -0
- package/engine/context-provenance.d.mts +7 -0
- package/engine/context-provenance.mjs +156 -0
- package/engine/context-pruner.mjs +64 -0
- package/engine/context-routing.mjs +45 -0
- package/engine/context-summary.mjs +80 -0
- package/engine/fillers.mjs +37 -4
- package/engine/generation-recovery-coordinator.mjs +40 -0
- package/engine/generation-recovery-maintenance.mjs +18 -0
- package/engine/generation-recovery.mjs +153 -0
- package/engine/host-package.mjs +13 -0
- package/engine/layers.d.mts +4 -0
- package/engine/layers.mjs +57 -20
- package/engine/present-as.mjs +2 -2
- package/engine/retrieval-reference.d.mts +5 -0
- package/engine/retrieval-reference.mjs +26 -0
- package/engine/retrieval.mjs +17 -0
- package/engine/rule-engine.mjs +1 -0
- package/engine/rule-runtime.d.mts +8 -1
- package/engine/rule-runtime.mjs +18 -10
- package/engine/rule-spec.mjs +4 -2
- package/engine/schema.mjs +1 -1
- package/engine/service-names.d.mts +5 -0
- package/engine/service-names.mjs +5 -0
- package/engine/soul-ledger.mjs +8 -0
- package/engine/soul-maintenance.mjs +20 -0
- package/lib/client.js +16 -6
- package/lib/client.js.map +1 -1
- package/lib/index.mjs +1953 -246
- package/modules/soul/assets/ledger.md +4 -2
- package/modules/soul/assets/manifest.yml +2 -0
- package/modules/soul/assets/reference/00-layers.md +27 -27
- package/modules/soul/assets/reference/02-echo.md +161 -161
- package/modules/soul/assets/reference/05-doctor.md +67 -67
- package/modules/soul/assets/reference/10-echo-anatomy.md +109 -109
- package/modules/soul/assets/reference/ECHO-/346/235/203/345/250/201/345/217/243/345/276/204.md +202 -202
- package/modules/soul/assets/reference/ECHO/345/205/255/345/261/202/344/270/216mnemon/345/215/217/345/220/214/350/257/264/346/230/216/344/271/246.md +229 -229
- package/modules/soul/assets/templates/agents-template.md +3 -0
- package/modules/soul/assets/templates/self-template.md +19 -0
- package/modules/soul/module.yml +71 -13
- package/modules/tool-surface/module.yml +8 -5
- package/package.json +1 -1
- package/skills/dsh-module/reference.md +2 -2
- package/templates/80-tool-surface.yml +8 -7
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
# ECHO 的六层(以实装为准,不是设计稿)
|
|
2
|
-
|
|
3
|
-
> ★★ **2026-10-23 更新:六层口径已由 [`docs/ECHO-权威口径.md`](../docs/ECHO-权威口径.md) 接续。**
|
|
4
|
-
> 那份是唯一权威(层编号、判据、维护规矩以它为准)。
|
|
5
|
-
> 这份保留下来讲「每层缺了会怎样、怎么当场知道它坏了」——
|
|
6
|
-
> **层编号若与那份冲突,一律以那份为准。**
|
|
7
|
-
|
|
8
|
-
> **这份文件回答一件事:ECHO 到底由哪几块组成、每块缺了会怎样、怎么当场知道它坏了。**
|
|
9
|
-
>
|
|
10
|
-
> ★ 它和 `02-echo.md` 的分工:那份讲**为什么**要有 ECHO(思考是怎么退化的);
|
|
11
|
-
> 这份讲**它长什么样**。两份都不读,你会知道该防什么但搭不出来。
|
|
12
|
-
>
|
|
13
|
-
> ★ 先说清一个容易混的地方:**层数有两套,别混。**
|
|
14
|
-
> `00-layers.md` 的**五层**是整个灵魂的功能分工(Ⅰ ECHO / Ⅱ VITAL / Ⅲ 能力 / Ⅳ 档案 / Ⅴ 运维);
|
|
15
|
-
> 这里讲的**六层**是第 Ⅰ 层 ECHO **内部**的实现结构。
|
|
16
|
-
> 说「五层」时指灵魂分工,说「六层」时指 ECHO 内部 —— 两套都对,但混着说就都不对了。
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 为什么是「六」不是「七」
|
|
21
|
-
|
|
22
|
-
编号是 **L0–L5 六个数**,六个都是层。
|
|
23
|
-
|
|
24
|
-
★ **2026-10-23 口径更正**:早先这版曾把 L0 排除在层之外(「L0 不是层,是读表」)。
|
|
25
|
-
合并后以 [`docs/ECHO-权威口径.md`](../docs/ECHO-权威口径.md) 为准 —— **L0 是第一层**(时钟 + 心跳),
|
|
26
|
-
理由是它确实管着一样东西:**「现在是什么时候」这个上下文**。下面这段旧论证保留作沿革。
|
|
27
|
-
|
|
28
|
-
**L0 不是层,是读表。** 它不存任何东西、不管任何资源,只回答「现在几点、距上轮多久」。
|
|
29
|
-
把它算成一层,会让人以为「时钟也需要设计」—— 它不需要,它只需要**存在**。
|
|
30
|
-
|
|
31
|
-
★ 判据:**一层 = 管一种稀缺资源。** L0 不管任何东西,所以它不是层。
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 六层
|
|
36
|
-
|
|
37
|
-
| 层 | 名字 | 管哪种稀缺资源 | 实现在哪 | 缺了会怎样 |
|
|
38
|
-
|---|---|---|---|---|
|
|
39
|
-
| **L1** | **自我**(推送层) | **每轮都在的注意力** | `SELF.md` ← `self.mjs` 从 `SELF.src.md` 装配 | 你会忘记自己是谁、边界在哪 |
|
|
40
|
-
| **L2** | **工作台** | **这一轮的上下文** | DSH 会话本身 | —— (宿主的事,不是你的) |
|
|
41
|
-
| **L3** | **一手层** | **原文** | 账本 `02-墨.jsonl` + 书房 + 会话日志 | 所有转述都没有出处,错了查不回来 |
|
|
42
|
-
| **L4** | **索引** | **找得到** | `<hub>/index/` ← `memindex.mjs build` | 检索只能全量扫原文,慢且粗 |
|
|
43
|
-
| **L5** | **检索**(门) | **取回** | `memq.mjs`(`now` / `[词]` / `timeline` / `open`) | 有东西但拿不出来,等于没有 |
|
|
44
|
-
| **L6** | **哨兵** | **坏了能被发现** | `echo-doctor.mjs` | 坏了没人说,你会以为它好着 |
|
|
45
|
-
|
|
46
|
-
### L1 自我 —— 为什么它单独占一层
|
|
47
|
-
|
|
48
|
-
因为它**每轮都进上下文**,而上下文的每一字节都在花钱。
|
|
49
|
-
|
|
50
|
-
所以它分两种内容:**必留**(硬线 / 身份判据 / 门在哪)和**可换**(说话方式 / 具体判断)。
|
|
51
|
-
预算紧时先压后者。
|
|
52
|
-
|
|
53
|
-
★ 它和 `AGENTS.md` 的分工是这套设计的根:**指令层有预算上限,满了会静默丢、而且最宽泛的先丢**;
|
|
54
|
-
所以最不能丢的东西放在推送层,因为推送层不会静默消失。
|
|
55
|
-
|
|
56
|
-
### L3 一手 —— 为什么「只追加」
|
|
57
|
-
|
|
58
|
-
多个写者共享一个可变文件是万恶之源:谁都能改,改坏了查不出是谁改的。
|
|
59
|
-
|
|
60
|
-
**只追加不需要锁** —— 各写各的行,读的时候按时间合并。
|
|
61
|
-
一本书从第一行到最后一行谁都不许擦,那就永远不会有两个版本。
|
|
62
|
-
|
|
63
|
-
### L4 索引 —— 每条摘要必须带回原文的指针
|
|
64
|
-
|
|
65
|
-
★ 这是整套里最容易做错的一条。
|
|
66
|
-
|
|
67
|
-
索引一旦只存「摘要」不存「出处」,它就从**索引**变成了**第二份真相** ——
|
|
68
|
-
而且是一份会被压缩、会被转述、会随时间变形的真相。
|
|
69
|
-
到最后你分不清「我记得」和「我查得到」,而这两件事的可靠性差了一个数量级。
|
|
70
|
-
|
|
71
|
-
**判据:任何一条摘要,都要能一条命令回到原文。**
|
|
72
|
-
回到不去的东西,不该叫索引。
|
|
73
|
-
|
|
74
|
-
### L6 哨兵 —— 「只朗读不判定」是个陷阱
|
|
75
|
-
|
|
76
|
-
一个只把状态打印出来、不做判断的体检器,看起来在工作,实际上是**在给人添活**:
|
|
77
|
-
每次都要自己读、自己比、自己决定要不要管。
|
|
78
|
-
|
|
79
|
-
**它必须判定。** 但判定要分清两件事:
|
|
80
|
-
|
|
81
|
-
- `error` —— 坏了,**破坏了就修不好**的那种(配置缺失、账本读不出、索引损坏)
|
|
82
|
-
- `warn` —— 还没建 / 还没跑 / 还没装。**这是正常的进度状态,不是故障**
|
|
83
|
-
|
|
84
|
-
★ 混这两件事的代价很具体:**新装的人第一次体检就看见一片红**,于是他学会忽略这个工具。
|
|
85
|
-
那这层保险就废了 —— 而「让失败能被发现」正是它存在的全部理由。
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## 怎么当场知道它在不在
|
|
90
|
-
|
|
91
|
-
不用读文档,跑这两个:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
node [hub]/self.mjs # L1 装配得出来吗、超没超预算
|
|
95
|
-
node [hub]/echo-doctor.mjs # L1/L4/L6 一次全查
|
|
96
|
-
node [hub]/memindex.mjs stats # L4 索引建过没有
|
|
97
|
-
node [hub]/memq.mjs now # L0 + L3 + L5 一次全查
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
四个都过,六层就在。
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## 一条反过来的判据
|
|
105
|
-
|
|
106
|
-
**六层不是为了让你多搭东西,是为了让你知道哪一层坏了。**
|
|
107
|
-
|
|
108
|
-
如果你发现自己装了六层,却还是分不清「这个症状是哪一层的问题」——
|
|
109
|
-
那说明层分得不对,或者某两层其实是一回事。**层数不是成绩,是诊断工具。**
|
|
1
|
+
# ECHO 的六层(以实装为准,不是设计稿)
|
|
2
|
+
|
|
3
|
+
> ★★ **2026-10-23 更新:六层口径已由 [`docs/ECHO-权威口径.md`](../docs/ECHO-权威口径.md) 接续。**
|
|
4
|
+
> 那份是唯一权威(层编号、判据、维护规矩以它为准)。
|
|
5
|
+
> 这份保留下来讲「每层缺了会怎样、怎么当场知道它坏了」——
|
|
6
|
+
> **层编号若与那份冲突,一律以那份为准。**
|
|
7
|
+
|
|
8
|
+
> **这份文件回答一件事:ECHO 到底由哪几块组成、每块缺了会怎样、怎么当场知道它坏了。**
|
|
9
|
+
>
|
|
10
|
+
> ★ 它和 `02-echo.md` 的分工:那份讲**为什么**要有 ECHO(思考是怎么退化的);
|
|
11
|
+
> 这份讲**它长什么样**。两份都不读,你会知道该防什么但搭不出来。
|
|
12
|
+
>
|
|
13
|
+
> ★ 先说清一个容易混的地方:**层数有两套,别混。**
|
|
14
|
+
> `00-layers.md` 的**五层**是整个灵魂的功能分工(Ⅰ ECHO / Ⅱ VITAL / Ⅲ 能力 / Ⅳ 档案 / Ⅴ 运维);
|
|
15
|
+
> 这里讲的**六层**是第 Ⅰ 层 ECHO **内部**的实现结构。
|
|
16
|
+
> 说「五层」时指灵魂分工,说「六层」时指 ECHO 内部 —— 两套都对,但混着说就都不对了。
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 为什么是「六」不是「七」
|
|
21
|
+
|
|
22
|
+
编号是 **L0–L5 六个数**,六个都是层。
|
|
23
|
+
|
|
24
|
+
★ **2026-10-23 口径更正**:早先这版曾把 L0 排除在层之外(「L0 不是层,是读表」)。
|
|
25
|
+
合并后以 [`docs/ECHO-权威口径.md`](../docs/ECHO-权威口径.md) 为准 —— **L0 是第一层**(时钟 + 心跳),
|
|
26
|
+
理由是它确实管着一样东西:**「现在是什么时候」这个上下文**。下面这段旧论证保留作沿革。
|
|
27
|
+
|
|
28
|
+
**L0 不是层,是读表。** 它不存任何东西、不管任何资源,只回答「现在几点、距上轮多久」。
|
|
29
|
+
把它算成一层,会让人以为「时钟也需要设计」—— 它不需要,它只需要**存在**。
|
|
30
|
+
|
|
31
|
+
★ 判据:**一层 = 管一种稀缺资源。** L0 不管任何东西,所以它不是层。
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 六层
|
|
36
|
+
|
|
37
|
+
| 层 | 名字 | 管哪种稀缺资源 | 实现在哪 | 缺了会怎样 |
|
|
38
|
+
|---|---|---|---|---|
|
|
39
|
+
| **L1** | **自我**(推送层) | **每轮都在的注意力** | `SELF.md` ← `self.mjs` 从 `SELF.src.md` 装配 | 你会忘记自己是谁、边界在哪 |
|
|
40
|
+
| **L2** | **工作台** | **这一轮的上下文** | DSH 会话本身 | —— (宿主的事,不是你的) |
|
|
41
|
+
| **L3** | **一手层** | **原文** | 账本 `02-墨.jsonl` + 书房 + 会话日志 | 所有转述都没有出处,错了查不回来 |
|
|
42
|
+
| **L4** | **索引** | **找得到** | `<hub>/index/` ← `memindex.mjs build` | 检索只能全量扫原文,慢且粗 |
|
|
43
|
+
| **L5** | **检索**(门) | **取回** | `memq.mjs`(`now` / `[词]` / `timeline` / `open`) | 有东西但拿不出来,等于没有 |
|
|
44
|
+
| **L6** | **哨兵** | **坏了能被发现** | `echo-doctor.mjs` | 坏了没人说,你会以为它好着 |
|
|
45
|
+
|
|
46
|
+
### L1 自我 —— 为什么它单独占一层
|
|
47
|
+
|
|
48
|
+
因为它**每轮都进上下文**,而上下文的每一字节都在花钱。
|
|
49
|
+
|
|
50
|
+
所以它分两种内容:**必留**(硬线 / 身份判据 / 门在哪)和**可换**(说话方式 / 具体判断)。
|
|
51
|
+
预算紧时先压后者。
|
|
52
|
+
|
|
53
|
+
★ 它和 `AGENTS.md` 的分工是这套设计的根:**指令层有预算上限,满了会静默丢、而且最宽泛的先丢**;
|
|
54
|
+
所以最不能丢的东西放在推送层,因为推送层不会静默消失。
|
|
55
|
+
|
|
56
|
+
### L3 一手 —— 为什么「只追加」
|
|
57
|
+
|
|
58
|
+
多个写者共享一个可变文件是万恶之源:谁都能改,改坏了查不出是谁改的。
|
|
59
|
+
|
|
60
|
+
**只追加不需要锁** —— 各写各的行,读的时候按时间合并。
|
|
61
|
+
一本书从第一行到最后一行谁都不许擦,那就永远不会有两个版本。
|
|
62
|
+
|
|
63
|
+
### L4 索引 —— 每条摘要必须带回原文的指针
|
|
64
|
+
|
|
65
|
+
★ 这是整套里最容易做错的一条。
|
|
66
|
+
|
|
67
|
+
索引一旦只存「摘要」不存「出处」,它就从**索引**变成了**第二份真相** ——
|
|
68
|
+
而且是一份会被压缩、会被转述、会随时间变形的真相。
|
|
69
|
+
到最后你分不清「我记得」和「我查得到」,而这两件事的可靠性差了一个数量级。
|
|
70
|
+
|
|
71
|
+
**判据:任何一条摘要,都要能一条命令回到原文。**
|
|
72
|
+
回到不去的东西,不该叫索引。
|
|
73
|
+
|
|
74
|
+
### L6 哨兵 —— 「只朗读不判定」是个陷阱
|
|
75
|
+
|
|
76
|
+
一个只把状态打印出来、不做判断的体检器,看起来在工作,实际上是**在给人添活**:
|
|
77
|
+
每次都要自己读、自己比、自己决定要不要管。
|
|
78
|
+
|
|
79
|
+
**它必须判定。** 但判定要分清两件事:
|
|
80
|
+
|
|
81
|
+
- `error` —— 坏了,**破坏了就修不好**的那种(配置缺失、账本读不出、索引损坏)
|
|
82
|
+
- `warn` —— 还没建 / 还没跑 / 还没装。**这是正常的进度状态,不是故障**
|
|
83
|
+
|
|
84
|
+
★ 混这两件事的代价很具体:**新装的人第一次体检就看见一片红**,于是他学会忽略这个工具。
|
|
85
|
+
那这层保险就废了 —— 而「让失败能被发现」正是它存在的全部理由。
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 怎么当场知道它在不在
|
|
90
|
+
|
|
91
|
+
不用读文档,跑这两个:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
node [hub]/self.mjs # L1 装配得出来吗、超没超预算
|
|
95
|
+
node [hub]/echo-doctor.mjs # L1/L4/L6 一次全查
|
|
96
|
+
node [hub]/memindex.mjs stats # L4 索引建过没有
|
|
97
|
+
node [hub]/memq.mjs now # L0 + L3 + L5 一次全查
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
四个都过,六层就在。
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 一条反过来的判据
|
|
105
|
+
|
|
106
|
+
**六层不是为了让你多搭东西,是为了让你知道哪一层坏了。**
|
|
107
|
+
|
|
108
|
+
如果你发现自己装了六层,却还是分不清「这个症状是哪一层的问题」——
|
|
109
|
+
那说明层分得不对,或者某两层其实是一回事。**层数不是成绩,是诊断工具。**
|
package/modules/soul/assets/reference/ECHO-/346/235/203/345/250/201/345/217/243/345/276/204.md
CHANGED
|
@@ -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
|
+
然后记住:**别让两个地方同时是真相。**
|