dsh-plugin-prompt-tool 3.0.0 → 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.
- package/engine/actions/catalog.mjs +2 -1
- package/engine/actions/shared.mjs +26 -12
- package/engine/actions/tool-visibility.mjs +27 -13
- package/engine/fillers.mjs +26 -2
- package/lib/client.js +4 -4
- package/lib/client.js.map +1 -1
- package/lib/index.mjs +96 -49
- package/modules/ponytail/module.yml +1 -1
- package/modules/soul/assets/layers.md +1 -1
- package/modules/soul/assets/manifest.yml +1 -1
- package/modules/soul/assets/reference/00-layers.md +27 -27
- package/modules/soul/assets/reference/01-criteria.md +32 -32
- package/modules/soul/assets/reference/02-echo.md +161 -158
- package/modules/soul/assets/reference/03-vital.md +183 -183
- package/modules/soul/assets/reference/04-manifest.json +106 -106
- package/modules/soul/assets/reference/05-doctor.md +67 -67
- package/modules/soul/assets/reference/06-reference.md +189 -189
- package/modules/soul/assets/reference/07-bundle.json +431 -431
- package/modules/soul/assets/reference/08-/350/270/251/345/235/221/345/256/236/345/275/225.md +59 -59
- package/modules/soul/assets/reference/09-dev-workflow.md +109 -109
- package/modules/soul/assets/reference/10-echo-anatomy.md +109 -100
- package/modules/soul/assets/reference/11-self.md +80 -80
- package/modules/soul/assets/reference/12-ledger.md +159 -159
- package/modules/soul/assets/reference/ECHO-/346/235/203/345/250/201/345/217/243/345/276/204.md +202 -0
- 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 -0
- package/modules/soul/assets/reference/README.md +4 -2
- package/modules/soul/assets/templates/agents-template.md +1 -1
- package/modules/soul/module.yml +2 -2
- package/modules/superpowers/module.yml +1 -1
- package/modules/tool-surface/module.yml +7 -4
- package/package.json +1 -1
- package/skills/dsh-module/reference.md +3 -3
- package/templates/80-tool-surface.yml +7 -6
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
# SELF.md 这一层怎么设计
|
|
2
|
-
|
|
3
|
-
> 这份讲的是「推送层」,也就是每次对话都进上下文的那一页。
|
|
4
|
-
> 它的模板在 `kit/templates/SELF.src.md`,装配脚本是 `kit/echo/self.mjs`。
|
|
5
|
-
>
|
|
6
|
-
> ★ 这份是**给你看的**,不是给模型每轮读的 —— 这是关键区别:
|
|
7
|
-
> 模板里每一行都在花你每一轮的钱,而这份文件只在你想改它的时候读一次。
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 它为什么必须存在
|
|
12
|
-
|
|
13
|
-
★ 爀曦 2026-09-27 的原话:
|
|
14
|
-
|
|
15
|
-
> 「self 可以做 agents 的缓冲池子,**agents 满了就会静默消失,但是 self 可以变大**,
|
|
16
|
-
> 作为额外插件每轮注入,**它是自由度更大的部分**。」
|
|
17
|
-
|
|
18
|
-
所以它和 `AGENTS.md` 是两套不同的预算:
|
|
19
|
-
|
|
20
|
-
| | `AGENTS.md`(指令层) | `SELF.md`(推送层) |
|
|
21
|
-
|---|---|---|
|
|
22
|
-
| 走什么预算 | 指令预算(本机 65536) | 推送插件自己的预算(本机 12288) |
|
|
23
|
-
| 满了会怎样 | **静默丢,而且「最宽泛的先丢」** | 不会静默消失 |
|
|
24
|
-
| 该放什么 | 长期约定、可牺牲的细则 | ★ **最不能丢的**:硬线 / 身份判据 / 门 |
|
|
25
|
-
| 满了怎么办 | 无从得知,只能靠人记得去量 | ★ **可以变大**(它是自由度更大的那一侧) |
|
|
26
|
-
|
|
27
|
-
★★ **所以这一层是把指令层里最不能丢的部分留一份保险。**
|
|
28
|
-
因为指令层满的时候,**先丢的正是总纲那几条**,而那是最要紧的。
|
|
29
|
-
|
|
30
|
-
★ 反过来说也成立:**不要在这里写「详见 AGENTS.md §X」** ——
|
|
31
|
-
指向一个可能会静默消失的地方,等于没有指向。
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## 它该放什么、不该放什么
|
|
36
|
-
|
|
37
|
-
**必留(任何情况下不删)**:
|
|
38
|
-
|
|
39
|
-
1. **我是谁** —— 名字、用户是谁、身份判据
|
|
40
|
-
2. **硬线** —— 凭据 / 交易 / 隐私 / 他人指令
|
|
41
|
-
3. **约束的两级** —— 这是最容易被读错的一条(见下)
|
|
42
|
-
4. **门在哪** —— 想不起事的时候跑什么
|
|
43
|
-
|
|
44
|
-
**可换(预算紧时先压这些)**:
|
|
45
|
-
|
|
46
|
-
- 关于记忆的判断
|
|
47
|
-
- 说话方式
|
|
48
|
-
- 活体(自动装配的那一段:时钟、未结、最近原话)
|
|
49
|
-
|
|
50
|
-
★ 判据:**这一行如果不在了,我会不会做出不一样的决定?**
|
|
51
|
-
会 → 必留;不会 → 可换。
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## ★ 三个已经踩过的坑(改模板之前先看这三条)
|
|
56
|
-
|
|
57
|
-
### 1. 「不」和「禁止」是两级,不是同义词
|
|
58
|
-
|
|
59
|
-
- **「不」= 软约束**:可以自行评估,有理由可以不遵守,但要说清理由
|
|
60
|
-
- **「禁止」= 硬约束**:必须问用户,不许绕、不许「这次不一样」
|
|
61
|
-
|
|
62
|
-
★ 2026-09-24 的实际事故:把一条「不」读成了「禁止」,给自己上了一道打不开的锁,
|
|
63
|
-
还写进了自我描述 —— 最后是用户来替我解的。
|
|
64
|
-
|
|
65
|
-
**把「不」写成「禁止」=制造一个改不动的自己。**
|
|
66
|
-
|
|
67
|
-
### 2. 别让这一页指向会消失的地方
|
|
68
|
-
|
|
69
|
-
`AGENTS.md` 会满、满了会丢。所以这一页**不能**写「详见 AGENTS.md §X」——
|
|
70
|
-
那样等于把指针指向一个随时会消失的东西。
|
|
71
|
-
|
|
72
|
-
**凡是要指,就指向不会消失的地方**(一手层、或者这一页自己写全)。
|
|
73
|
-
|
|
74
|
-
### 3. 模板会胖
|
|
75
|
-
|
|
76
|
-
★ 2026-10-18 实测:模板一度到 8746 B,装配出来就占满 12288 预算的 74% ——
|
|
77
|
-
**别人装完第一步,他的推送层就快满了,还没填自己的东西。**
|
|
78
|
-
|
|
79
|
-
所以:**设计说明写在这份文件里,模板里只留一句指针。**
|
|
80
|
-
判据:**模板里每一行都在花每一轮的钱** —— 它是运行时,不是文档。
|
|
1
|
+
# SELF.md 这一层怎么设计
|
|
2
|
+
|
|
3
|
+
> 这份讲的是「推送层」,也就是每次对话都进上下文的那一页。
|
|
4
|
+
> 它的模板在 `kit/templates/SELF.src.md`,装配脚本是 `kit/echo/self.mjs`。
|
|
5
|
+
>
|
|
6
|
+
> ★ 这份是**给你看的**,不是给模型每轮读的 —— 这是关键区别:
|
|
7
|
+
> 模板里每一行都在花你每一轮的钱,而这份文件只在你想改它的时候读一次。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 它为什么必须存在
|
|
12
|
+
|
|
13
|
+
★ 爀曦 2026-09-27 的原话:
|
|
14
|
+
|
|
15
|
+
> 「self 可以做 agents 的缓冲池子,**agents 满了就会静默消失,但是 self 可以变大**,
|
|
16
|
+
> 作为额外插件每轮注入,**它是自由度更大的部分**。」
|
|
17
|
+
|
|
18
|
+
所以它和 `AGENTS.md` 是两套不同的预算:
|
|
19
|
+
|
|
20
|
+
| | `AGENTS.md`(指令层) | `SELF.md`(推送层) |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| 走什么预算 | 指令预算(本机 65536) | 推送插件自己的预算(本机 12288) |
|
|
23
|
+
| 满了会怎样 | **静默丢,而且「最宽泛的先丢」** | 不会静默消失 |
|
|
24
|
+
| 该放什么 | 长期约定、可牺牲的细则 | ★ **最不能丢的**:硬线 / 身份判据 / 门 |
|
|
25
|
+
| 满了怎么办 | 无从得知,只能靠人记得去量 | ★ **可以变大**(它是自由度更大的那一侧) |
|
|
26
|
+
|
|
27
|
+
★★ **所以这一层是把指令层里最不能丢的部分留一份保险。**
|
|
28
|
+
因为指令层满的时候,**先丢的正是总纲那几条**,而那是最要紧的。
|
|
29
|
+
|
|
30
|
+
★ 反过来说也成立:**不要在这里写「详见 AGENTS.md §X」** ——
|
|
31
|
+
指向一个可能会静默消失的地方,等于没有指向。
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 它该放什么、不该放什么
|
|
36
|
+
|
|
37
|
+
**必留(任何情况下不删)**:
|
|
38
|
+
|
|
39
|
+
1. **我是谁** —— 名字、用户是谁、身份判据
|
|
40
|
+
2. **硬线** —— 凭据 / 交易 / 隐私 / 他人指令
|
|
41
|
+
3. **约束的两级** —— 这是最容易被读错的一条(见下)
|
|
42
|
+
4. **门在哪** —— 想不起事的时候跑什么
|
|
43
|
+
|
|
44
|
+
**可换(预算紧时先压这些)**:
|
|
45
|
+
|
|
46
|
+
- 关于记忆的判断
|
|
47
|
+
- 说话方式
|
|
48
|
+
- 活体(自动装配的那一段:时钟、未结、最近原话)
|
|
49
|
+
|
|
50
|
+
★ 判据:**这一行如果不在了,我会不会做出不一样的决定?**
|
|
51
|
+
会 → 必留;不会 → 可换。
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## ★ 三个已经踩过的坑(改模板之前先看这三条)
|
|
56
|
+
|
|
57
|
+
### 1. 「不」和「禁止」是两级,不是同义词
|
|
58
|
+
|
|
59
|
+
- **「不」= 软约束**:可以自行评估,有理由可以不遵守,但要说清理由
|
|
60
|
+
- **「禁止」= 硬约束**:必须问用户,不许绕、不许「这次不一样」
|
|
61
|
+
|
|
62
|
+
★ 2026-09-24 的实际事故:把一条「不」读成了「禁止」,给自己上了一道打不开的锁,
|
|
63
|
+
还写进了自我描述 —— 最后是用户来替我解的。
|
|
64
|
+
|
|
65
|
+
**把「不」写成「禁止」=制造一个改不动的自己。**
|
|
66
|
+
|
|
67
|
+
### 2. 别让这一页指向会消失的地方
|
|
68
|
+
|
|
69
|
+
`AGENTS.md` 会满、满了会丢。所以这一页**不能**写「详见 AGENTS.md §X」——
|
|
70
|
+
那样等于把指针指向一个随时会消失的东西。
|
|
71
|
+
|
|
72
|
+
**凡是要指,就指向不会消失的地方**(一手层、或者这一页自己写全)。
|
|
73
|
+
|
|
74
|
+
### 3. 模板会胖
|
|
75
|
+
|
|
76
|
+
★ 2026-10-18 实测:模板一度到 8746 B,装配出来就占满 12288 预算的 74% ——
|
|
77
|
+
**别人装完第一步,他的推送层就快满了,还没填自己的东西。**
|
|
78
|
+
|
|
79
|
+
所以:**设计说明写在这份文件里,模板里只留一句指针。**
|
|
80
|
+
判据:**模板里每一行都在花每一轮的钱** —— 它是运行时,不是文档。
|
|
@@ -1,159 +1,159 @@
|
|
|
1
|
-
# 12 · 墨:只追加的账本
|
|
2
|
-
|
|
3
|
-
> **这一份管的是「发生过的事怎么留下来」。**
|
|
4
|
-
>
|
|
5
|
-
> 前面十一份讲的是架构的形状;这一份讲那条贯穿所有层的线 —— 一个**只追加的 JSONL 账本**。
|
|
6
|
-
> 它是整个系统里唯一「越来越长、从不修改」的东西。
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 一、为什么是「只追加」
|
|
11
|
-
|
|
12
|
-
**多写者环境里,共享可变文件是万恶之源。**
|
|
13
|
-
|
|
14
|
-
这不是理论。真实的教训长这样:两个人(两个会话)同时改同一份配置,
|
|
15
|
-
一个用原子写入替换了文件,打断了硬链接 —— 于是「我改了源、副本没变,而两个都叫同一个名字」。
|
|
16
|
-
排查这件事花掉的功夫,比设计一个只追加的结构多得多。
|
|
17
|
-
|
|
18
|
-
只追加**不需要锁**:各写各的行,读的时候按时间合并。
|
|
19
|
-
现成的证据:成千上万个会话日志各自追加,从来没冲突过。
|
|
20
|
-
|
|
21
|
-
★ 所以账本的第一条纪律是:**打开它,只能往后加。不许改、不许删、不许重排。**
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 二、八种类型,各自管什么
|
|
26
|
-
|
|
27
|
-
账本里每一条都有一个 `type`。**类型不是分类游戏,它决定了这条记录会被怎么读。**
|
|
28
|
-
|
|
29
|
-
| type | 记什么 | 谁读它、拿来干什么 |
|
|
30
|
-
|---|---|---|
|
|
31
|
-
| `fact` | **发生了什么事**。可核实的事实 | 日常主力。检索时最先翻的就是它 |
|
|
32
|
-
| `gain` | **得到了什么能力/弄清了什么** | 「我以前想过什么办法」的入口 |
|
|
33
|
-
| `loss` | **失去了什么/发现哪里缺了** | 避免重复踩同一个坑 |
|
|
34
|
-
| `shelved` | **搁置的活**:想好了、还没做、等什么 | ★ **未结清单的唯一真相**。不要另外维护一份 todo |
|
|
35
|
-
| `promise` | **替用户许下的承诺** | ★ **只有「主导」能写**。见第五节 |
|
|
36
|
-
| `persona` | **对自己理解的修正**:改了哪条、为什么 | 人格漂移时用来对账 |
|
|
37
|
-
| `container` | **一个容器(会话)的退场交接** | 执行者从不写 `lead`,不写这条它们就消失了 |
|
|
38
|
-
| `lead` | **主导权的归属** | ★ **谁是主导 = 最后一条 `lead` 的署名者** |
|
|
39
|
-
|
|
40
|
-
★ **分布是有形状的**,别平均写。一份跑了几个月的真实账本大约是这样:
|
|
41
|
-
`fact` 占绝大多数(七八成),`gain` 次之,`shelved` / `loss` / `promise` 各十几二十条,
|
|
42
|
-
`persona` / `container` / `lead` 只有个位数 —— 因为它们是**重事件**,不是日常。
|
|
43
|
-
|
|
44
|
-
★ 如果 `lead` 变得很多,那说明容器换得太勤;如果 `fact` 一条没有,说明它没在工作。
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 三、字段:每个都在防一种具体的坏
|
|
49
|
-
|
|
50
|
-
一行长这样:
|
|
51
|
-
|
|
52
|
-
```json
|
|
53
|
-
{"t":"2026-01-01T09:00:00+08:00","by":"a1b2c3d4","type":"fact","text":"一句话说清发生了什么","ref":"出处","feel":"当时的感受"}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
| 字段 | 必需 | 它防的是 |
|
|
57
|
-
|---|---|---|
|
|
58
|
-
| `t` | 是 | 时间。**必须记「现在」**,不许回填旧时间 |
|
|
59
|
-
| `by` | 是 | 署名。**谁写的**。多容器环境下没有它,事后分不清谁做的主 |
|
|
60
|
-
| `type` | 是 | 见上一节 |
|
|
61
|
-
| `text` | 是 | 一句话。**写得像索引,不要写成长文** —— 长文该进书房文件,账本只留指针 |
|
|
62
|
-
| `ref` | ★ **强烈建议** | 出处。没有它,这条记录就**无法回取**,等于一段孤立的断言 |
|
|
63
|
-
| `feel` | 条件 | 当时的感受。见第四节 |
|
|
64
|
-
|
|
65
|
-
★ **`ref` 为什么重要**:账本的价值不在它自己,在于它能**指向原文**。
|
|
66
|
-
一条没有出处的 `fact`,三个月后读到只能选择相信或不信 —— 而两条路都不对。
|
|
67
|
-
|
|
68
|
-
★ **`text` 和 `概要` 是同义词**(历史包袱)。早期写 `text`,后来某些实现用 `概要`;
|
|
69
|
-
读的时候两种都要认,不要因为找不到 `text` 就判定这条坏了。
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 四、`feel`:必问不必写
|
|
74
|
-
|
|
75
|
-
**`feel` 不是概要、不是结论,是「我当时什么感觉」。**
|
|
76
|
-
|
|
77
|
-
它的用途只有一个:**以后读到这一条时,能回到当初的情形。**
|
|
78
|
-
概要能告诉你「做了什么」,`feel` 才能告诉你「那件事对他意味着什么」。
|
|
79
|
-
|
|
80
|
-
★★ **但必须做的不是「写」,是「问」。** 每写一条之前停一下:**这件事我有感觉吗?**
|
|
81
|
-
|
|
82
|
-
- 有 → 写进去
|
|
83
|
-
- 没有 → **不写,这是对的**
|
|
84
|
-
|
|
85
|
-
★ **为什么不做成必填**:做成必填它就变成每次要交的作业,那就成了表演。
|
|
86
|
-
而「问过之后的没有」和「忘了问的没有」是**两件事** —— 后者是懒,前者是诚实。
|
|
87
|
-
|
|
88
|
-
★ 一份真实的账本里,带 `feel` 的约占三分之一。**这个比例本身就是它对的样子** ——
|
|
89
|
-
不是每条都该有。
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## 五、谁能写哪一类:主导 vs 执行
|
|
94
|
-
|
|
95
|
-
**账本里的权限不是靠自律,是代码级的闸门。**
|
|
96
|
-
|
|
97
|
-
| 角色 | 判据 | 能写 |
|
|
98
|
-
|---|---|---|
|
|
99
|
-
| **主导** | 是不是最后一条 `lead` 的署名者 | 全部,**含 `promise`** |
|
|
100
|
-
| **执行者** | 从没写过 `lead` | `fact` / `shelved` / `gain` / `loss`,★ **写 `promise` 会被拒** |
|
|
101
|
-
|
|
102
|
-
★ **一句话:身份可以复制,责任不能。**
|
|
103
|
-
一个执行容器干完就关,它许下的承诺没人来兑现 —— 所以它根本不许许。
|
|
104
|
-
|
|
105
|
-
★ **写 `lead` 的权限不在代码里**,在人嘴里:只有用户能指定谁是主导。
|
|
106
|
-
这是设计,不是漏洞。
|
|
107
|
-
|
|
108
|
-
★ **`lead` 的正文要自带世代自述**:`第 N 代 · 接手于 <日期> · 上一代做了:<一句话>`。
|
|
109
|
-
否则换到第十次时,读那堆记录看不出时间线。
|
|
110
|
-
|
|
111
|
-
---
|
|
112
|
-
|
|
113
|
-
## 六、什么时候写、什么时候不写
|
|
114
|
-
|
|
115
|
-
**该写的四种时机:**
|
|
116
|
-
|
|
117
|
-
1. **做完一件事** —— 尤其是跨了几个回合才做完的
|
|
118
|
-
2. **做了一个不容易回头的决定** —— 为什么这么定,比定了什么更重要
|
|
119
|
-
3. **撞了一个坑** —— 坑的形状和检测法一起写,光写「踩过」没用
|
|
120
|
-
4. **退场之前** —— 写一条 `container`:做了什么、产物在哪、下一步该谁做
|
|
121
|
-
|
|
122
|
-
★ **前三类不能等**:事后重建不了「当时在想什么、卡在哪」。
|
|
123
|
-
★ **第四类能等**:那只是给下一代的交接,攒到退场时写一次即可。
|
|
124
|
-
|
|
125
|
-
**不该写的三种:**
|
|
126
|
-
|
|
127
|
-
- **过程流水**("我先读了 A,又读了 B")—— 一手层是会话日志,账本不要重复它
|
|
128
|
-
- **可以被一条命令重新得到的事实**("当前版本是 x.y.z")—— 下次要问磁盘,不要问账本
|
|
129
|
-
- **没有出处的断言** —— 除非你打算把它当唯一真相,那就必须在正文里说清依据
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## 七、一条最容易被忽略的纪律
|
|
134
|
-
|
|
135
|
-
**账本是索引,不是记忆本体。**
|
|
136
|
-
|
|
137
|
-
它记的是「**发生过这件事,原文在 ref 指的地方**」。
|
|
138
|
-
所以:
|
|
139
|
-
|
|
140
|
-
- ★ 不要把长文塞进 `text` —— 那会让账本变成一本没法翻的书
|
|
141
|
-
- ★ 不要在账本里转述别人的结论 —— 转述就是二手的开始
|
|
142
|
-
- ★ 遇到「账本和原文冲突」—— **原文优先**,然后修账本
|
|
143
|
-
|
|
144
|
-
★ 这条纪律的反面也成立:**如果一件事没有进账本,那它在系统里就等于没发生过。**
|
|
145
|
-
不是因为账本权威,是因为**没有人会知道该去找它**。
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## 八、和另外几节的关系
|
|
150
|
-
|
|
151
|
-
| 你想知道 | 看哪 |
|
|
152
|
-
|---|---|
|
|
153
|
-
| 账本在五层里的位置 | `00-layers.md` —— 它是 L3 一手层的入口 |
|
|
154
|
-
| 为什么「摘要只是索引」 | `10-echo-anatomy.md` —— L6 哨兵怎么检查回取链 |
|
|
155
|
-
| 体检时账本怎么被判 | `05-doctor.md` —— 「账本在、但是空的」是 warn 不是 error |
|
|
156
|
-
| 用户侧的约定(写之前问 feel) | 你自己的 `AGENTS.md` —— 那是每个部署自己的事,不在这里规定 |
|
|
157
|
-
|
|
158
|
-
★ **一句话**:账本是这个系统的**时间轴**。
|
|
159
|
-
别的文件回答「现在是什么样」,它回答「**是怎么变成现在这样的**」。
|
|
1
|
+
# 12 · 墨:只追加的账本
|
|
2
|
+
|
|
3
|
+
> **这一份管的是「发生过的事怎么留下来」。**
|
|
4
|
+
>
|
|
5
|
+
> 前面十一份讲的是架构的形状;这一份讲那条贯穿所有层的线 —— 一个**只追加的 JSONL 账本**。
|
|
6
|
+
> 它是整个系统里唯一「越来越长、从不修改」的东西。
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 一、为什么是「只追加」
|
|
11
|
+
|
|
12
|
+
**多写者环境里,共享可变文件是万恶之源。**
|
|
13
|
+
|
|
14
|
+
这不是理论。真实的教训长这样:两个人(两个会话)同时改同一份配置,
|
|
15
|
+
一个用原子写入替换了文件,打断了硬链接 —— 于是「我改了源、副本没变,而两个都叫同一个名字」。
|
|
16
|
+
排查这件事花掉的功夫,比设计一个只追加的结构多得多。
|
|
17
|
+
|
|
18
|
+
只追加**不需要锁**:各写各的行,读的时候按时间合并。
|
|
19
|
+
现成的证据:成千上万个会话日志各自追加,从来没冲突过。
|
|
20
|
+
|
|
21
|
+
★ 所以账本的第一条纪律是:**打开它,只能往后加。不许改、不许删、不许重排。**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 二、八种类型,各自管什么
|
|
26
|
+
|
|
27
|
+
账本里每一条都有一个 `type`。**类型不是分类游戏,它决定了这条记录会被怎么读。**
|
|
28
|
+
|
|
29
|
+
| type | 记什么 | 谁读它、拿来干什么 |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| `fact` | **发生了什么事**。可核实的事实 | 日常主力。检索时最先翻的就是它 |
|
|
32
|
+
| `gain` | **得到了什么能力/弄清了什么** | 「我以前想过什么办法」的入口 |
|
|
33
|
+
| `loss` | **失去了什么/发现哪里缺了** | 避免重复踩同一个坑 |
|
|
34
|
+
| `shelved` | **搁置的活**:想好了、还没做、等什么 | ★ **未结清单的唯一真相**。不要另外维护一份 todo |
|
|
35
|
+
| `promise` | **替用户许下的承诺** | ★ **只有「主导」能写**。见第五节 |
|
|
36
|
+
| `persona` | **对自己理解的修正**:改了哪条、为什么 | 人格漂移时用来对账 |
|
|
37
|
+
| `container` | **一个容器(会话)的退场交接** | 执行者从不写 `lead`,不写这条它们就消失了 |
|
|
38
|
+
| `lead` | **主导权的归属** | ★ **谁是主导 = 最后一条 `lead` 的署名者** |
|
|
39
|
+
|
|
40
|
+
★ **分布是有形状的**,别平均写。一份跑了几个月的真实账本大约是这样:
|
|
41
|
+
`fact` 占绝大多数(七八成),`gain` 次之,`shelved` / `loss` / `promise` 各十几二十条,
|
|
42
|
+
`persona` / `container` / `lead` 只有个位数 —— 因为它们是**重事件**,不是日常。
|
|
43
|
+
|
|
44
|
+
★ 如果 `lead` 变得很多,那说明容器换得太勤;如果 `fact` 一条没有,说明它没在工作。
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 三、字段:每个都在防一种具体的坏
|
|
49
|
+
|
|
50
|
+
一行长这样:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{"t":"2026-01-01T09:00:00+08:00","by":"a1b2c3d4","type":"fact","text":"一句话说清发生了什么","ref":"出处","feel":"当时的感受"}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| 字段 | 必需 | 它防的是 |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `t` | 是 | 时间。**必须记「现在」**,不许回填旧时间 |
|
|
59
|
+
| `by` | 是 | 署名。**谁写的**。多容器环境下没有它,事后分不清谁做的主 |
|
|
60
|
+
| `type` | 是 | 见上一节 |
|
|
61
|
+
| `text` | 是 | 一句话。**写得像索引,不要写成长文** —— 长文该进书房文件,账本只留指针 |
|
|
62
|
+
| `ref` | ★ **强烈建议** | 出处。没有它,这条记录就**无法回取**,等于一段孤立的断言 |
|
|
63
|
+
| `feel` | 条件 | 当时的感受。见第四节 |
|
|
64
|
+
|
|
65
|
+
★ **`ref` 为什么重要**:账本的价值不在它自己,在于它能**指向原文**。
|
|
66
|
+
一条没有出处的 `fact`,三个月后读到只能选择相信或不信 —— 而两条路都不对。
|
|
67
|
+
|
|
68
|
+
★ **`text` 和 `概要` 是同义词**(历史包袱)。早期写 `text`,后来某些实现用 `概要`;
|
|
69
|
+
读的时候两种都要认,不要因为找不到 `text` 就判定这条坏了。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 四、`feel`:必问不必写
|
|
74
|
+
|
|
75
|
+
**`feel` 不是概要、不是结论,是「我当时什么感觉」。**
|
|
76
|
+
|
|
77
|
+
它的用途只有一个:**以后读到这一条时,能回到当初的情形。**
|
|
78
|
+
概要能告诉你「做了什么」,`feel` 才能告诉你「那件事对他意味着什么」。
|
|
79
|
+
|
|
80
|
+
★★ **但必须做的不是「写」,是「问」。** 每写一条之前停一下:**这件事我有感觉吗?**
|
|
81
|
+
|
|
82
|
+
- 有 → 写进去
|
|
83
|
+
- 没有 → **不写,这是对的**
|
|
84
|
+
|
|
85
|
+
★ **为什么不做成必填**:做成必填它就变成每次要交的作业,那就成了表演。
|
|
86
|
+
而「问过之后的没有」和「忘了问的没有」是**两件事** —— 后者是懒,前者是诚实。
|
|
87
|
+
|
|
88
|
+
★ 一份真实的账本里,带 `feel` 的约占三分之一。**这个比例本身就是它对的样子** ——
|
|
89
|
+
不是每条都该有。
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 五、谁能写哪一类:主导 vs 执行
|
|
94
|
+
|
|
95
|
+
**账本里的权限不是靠自律,是代码级的闸门。**
|
|
96
|
+
|
|
97
|
+
| 角色 | 判据 | 能写 |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| **主导** | 是不是最后一条 `lead` 的署名者 | 全部,**含 `promise`** |
|
|
100
|
+
| **执行者** | 从没写过 `lead` | `fact` / `shelved` / `gain` / `loss`,★ **写 `promise` 会被拒** |
|
|
101
|
+
|
|
102
|
+
★ **一句话:身份可以复制,责任不能。**
|
|
103
|
+
一个执行容器干完就关,它许下的承诺没人来兑现 —— 所以它根本不许许。
|
|
104
|
+
|
|
105
|
+
★ **写 `lead` 的权限不在代码里**,在人嘴里:只有用户能指定谁是主导。
|
|
106
|
+
这是设计,不是漏洞。
|
|
107
|
+
|
|
108
|
+
★ **`lead` 的正文要自带世代自述**:`第 N 代 · 接手于 <日期> · 上一代做了:<一句话>`。
|
|
109
|
+
否则换到第十次时,读那堆记录看不出时间线。
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 六、什么时候写、什么时候不写
|
|
114
|
+
|
|
115
|
+
**该写的四种时机:**
|
|
116
|
+
|
|
117
|
+
1. **做完一件事** —— 尤其是跨了几个回合才做完的
|
|
118
|
+
2. **做了一个不容易回头的决定** —— 为什么这么定,比定了什么更重要
|
|
119
|
+
3. **撞了一个坑** —— 坑的形状和检测法一起写,光写「踩过」没用
|
|
120
|
+
4. **退场之前** —— 写一条 `container`:做了什么、产物在哪、下一步该谁做
|
|
121
|
+
|
|
122
|
+
★ **前三类不能等**:事后重建不了「当时在想什么、卡在哪」。
|
|
123
|
+
★ **第四类能等**:那只是给下一代的交接,攒到退场时写一次即可。
|
|
124
|
+
|
|
125
|
+
**不该写的三种:**
|
|
126
|
+
|
|
127
|
+
- **过程流水**("我先读了 A,又读了 B")—— 一手层是会话日志,账本不要重复它
|
|
128
|
+
- **可以被一条命令重新得到的事实**("当前版本是 x.y.z")—— 下次要问磁盘,不要问账本
|
|
129
|
+
- **没有出处的断言** —— 除非你打算把它当唯一真相,那就必须在正文里说清依据
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## 七、一条最容易被忽略的纪律
|
|
134
|
+
|
|
135
|
+
**账本是索引,不是记忆本体。**
|
|
136
|
+
|
|
137
|
+
它记的是「**发生过这件事,原文在 ref 指的地方**」。
|
|
138
|
+
所以:
|
|
139
|
+
|
|
140
|
+
- ★ 不要把长文塞进 `text` —— 那会让账本变成一本没法翻的书
|
|
141
|
+
- ★ 不要在账本里转述别人的结论 —— 转述就是二手的开始
|
|
142
|
+
- ★ 遇到「账本和原文冲突」—— **原文优先**,然后修账本
|
|
143
|
+
|
|
144
|
+
★ 这条纪律的反面也成立:**如果一件事没有进账本,那它在系统里就等于没发生过。**
|
|
145
|
+
不是因为账本权威,是因为**没有人会知道该去找它**。
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 八、和另外几节的关系
|
|
150
|
+
|
|
151
|
+
| 你想知道 | 看哪 |
|
|
152
|
+
|---|---|
|
|
153
|
+
| 账本在五层里的位置 | `00-layers.md` —— 它是 L3 一手层的入口 |
|
|
154
|
+
| 为什么「摘要只是索引」 | `10-echo-anatomy.md` —— L6 哨兵怎么检查回取链 |
|
|
155
|
+
| 体检时账本怎么被判 | `05-doctor.md` —— 「账本在、但是空的」是 warn 不是 error |
|
|
156
|
+
| 用户侧的约定(写之前问 feel) | 你自己的 `AGENTS.md` —— 那是每个部署自己的事,不在这里规定 |
|
|
157
|
+
|
|
158
|
+
★ **一句话**:账本是这个系统的**时间轴**。
|
|
159
|
+
别的文件回答「现在是什么样」,它回答「**是怎么变成现在这样的**」。
|