dsh-gokifu-compact 0.0.0-stage → 1.7.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/CHANGELOG.md +1023 -0
- package/QUICKSTART.md +124 -0
- package/README.md +257 -2
- package/docs/DSH-/346/212/200/346/234/257/346/265/213/347/273/230.md +1303 -0
- package/docs/P0-worldhash-/346/255/273/345/276/252/347/216/257-/346/240/271/345/233/240/344/270/216/344/277/256/345/244/215/346/226/271/346/241/210.md +244 -0
- package/docs/P0-worldhash-/346/255/273/345/276/252/347/216/257/344/277/256/345/244/215.patch +571 -0
- package/docs//344/270/211/345/261/202/346/240/221/350/256/276/350/256/241.md +87 -0
- package/docs//345/270/202/345/234/272/345/257/271/346/240/207.md +452 -0
- package/docs//346/200/247/350/203/275/344/270/216/346/210/220/346/234/254.md +106 -0
- package/docs//346/226/271/346/241/210/344/271/246.md +206 -0
- package/docs//346/234/200/347/273/210/346/212/245/345/221/212.md +183 -0
- package/docs//350/256/241/345/210/222/350/241/250.md +35 -0
- package/docs//350/277/220/350/241/214/346/234/237/344/277/256/345/244/215/346/212/245/345/221/212.md +169 -0
- package/docs//351/207/215/345/220/257/345/220/216/351/252/214/350/257/201/346/270/205/345/215/225.md +99 -0
- package/evidence/P0-worldhash-/344/277/256/345/244/215/351/252/214/350/257/201.md +139 -0
- package/evidence/P1-4-/346/270/205/345/215/225/346/233/277/346/215/242/345/256/236/346/265/213.md +98 -0
- package/evidence/bench-2000.json +20 -0
- package/evidence/fold/350/247/246/345/217/221/351/252/214/350/257/201.json +31 -0
- package/evidence/fold/350/247/246/345/217/221/351/252/214/350/257/201.md +36 -0
- package/evidence/ima-/346/221/230/350/246/201/346/265/213/350/257/225.json +139 -0
- package/evidence/ima-/346/221/230/350/246/201/346/265/213/350/257/225.md +188 -0
- package/evidence//344/270/211/346/200/201/346/240/207/347/255/276AB/345/256/236/351/252/214.md +71 -0
- package/evidence//346/224/266/345/260/276/344/270/211/344/273/266-dead/351/224/232/347/202/271-/346/240/221/350/257/273/345/217/226-/345/233/236/346/264/227.md +87 -0
- package/evidence//346/243/213/350/260/261/346/234/211/346/225/210/346/200/247/345/256/236/351/252/214.md +89 -0
- package/evidence//346/250/241/346/213/237/347/273/223/346/236/234.json +229 -0
- package/evidence//346/250/241/346/213/237/347/273/223/346/236/234.md +61 -0
- package/evidence//347/203/255/346/270/205/345/215/225/346/240/207/350/256/260AB/345/256/236/351/252/214.md +159 -0
- package/evidence//347/234/237/345/256/236/346/250/241/345/236/213/345/244/232/350/247/204/346/250/241/346/265/213/350/257/225.json +48 -0
- package/evidence//347/234/237/345/256/236/346/250/241/345/236/213/345/244/232/350/247/204/346/250/241/346/265/213/350/257/225.md +17 -0
- package/evidence//347/234/237/345/256/236/346/250/241/345/236/213/346/265/213/350/257/225.json +140 -0
- package/evidence//347/234/237/345/256/236/346/250/241/345/236/213/346/265/213/350/257/225.md +166 -0
- package/evidence//347/234/237/345/256/236/347/253/257/345/210/260/347/253/257/346/265/213/350/257/225.json +25 -0
- package/evidence//347/234/237/345/256/236/347/253/257/345/210/260/347/253/257/346/265/213/350/257/225.md +72 -0
- package/evidence//347/234/237/345/256/236/350/256/241/350/264/271/346/240/270/345/257/271.md +94 -0
- package/evidence//347/234/237/345/256/236/350/277/233/347/250/213/351/246/226/346/254/241fold.md +56 -0
- package/evidence//351/207/215/345/220/257/351/252/214/350/257/201.json +45 -0
- package/evidence//351/207/215/345/220/257/351/252/214/350/257/201.md +91 -0
- package/package.json +68 -4
- package/scripts/check-maintenance.mjs +146 -0
- package/scripts/release.mjs +389 -0
- package/src/engine.mjs +960 -0
- package/src/extract.mjs +90 -0
- package/src/graph.mjs +644 -0
- package/src/keeper.mjs +197 -0
- package/src/ledger.mjs +394 -0
- package/src/range.mjs +155 -0
- package/src/summary-prompt.mjs +117 -0
- package/src/verifier.mjs +199 -0
- package/src/worldstate.mjs +71 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
# 更新记录
|
|
2
|
+
|
|
3
|
+
## 1.7.0 — 2026-10-29
|
|
4
|
+
|
|
5
|
+
> 起因:自 v1.3.4 起累计 9 个版本未发布;本版是首个公开发布,汇总 1.3.5–1.6.3 的全部改动,
|
|
6
|
+
> 并把展示名统一为 `dsh-GOkifu-compact`(前缀小写、只有 GO 大写)。
|
|
7
|
+
|
|
8
|
+
### 首个公开发布(汇总 1.3.5 – 1.6.3)
|
|
9
|
+
|
|
10
|
+
**P0 修复:压缩 226 次只成功 3 次的根因**
|
|
11
|
+
- `worldHash` 类型契约(对象 → 字符串)+ `fromJSON` 加载边界自愈历史脏数据 + `stateIndex` 重建
|
|
12
|
+
- 实机 `session-5acafe42`:139 次 `worldHash?.slice is not a function`、223/226 次压缩失败;修后全库 1,279 个对象字段归零
|
|
13
|
+
|
|
14
|
+
**热清单(给模型看的那一小块)**
|
|
15
|
+
- 标记自带语义:`blocked:permission` / `dead retry-if:<edge>`;图例按用到的标记动态生成(出现即解释)
|
|
16
|
+
- 报错原文任何档位都不丢;手割多参照点(同一失败边相对每条成功路径分别结论)
|
|
17
|
+
- **清单就地替换**:surface 上永远只有一条(旧版累积过 176 条 / 81 万字符 ≈ 27 万 token)
|
|
18
|
+
- 历史清单一次性换成一行占位;2000 边渲染 0.478 ms / 323 tokens
|
|
19
|
+
|
|
20
|
+
**压缩本身**
|
|
21
|
+
- 增量 fold(只压 checkpoint 之后)+ 机械约束段
|
|
22
|
+
- 摘要三层降级:配置模型 → 路由模型 → 规则摘要(压缩永不因摘要模型挂掉而失败)
|
|
23
|
+
- 真实 dsh 进程里 fold 3~6 次全成功(`test/real-headless-fold.mjs`)
|
|
24
|
+
|
|
25
|
+
**工具与维护**
|
|
26
|
+
- `test/doctor.mjs` 体检、`test/measure-billing.mjs` 真实计费审计、`test/rewash-graph.mjs` 历史回洗、
|
|
27
|
+
`test/verify-graphs.mjs` 全库健康、`test/ab-render.mjs` 标记 A/B 夹具
|
|
28
|
+
- 仓库维护照搬 `magpie-plugin-scaffold`:`scripts/check-maintenance.mjs` + `scripts/release.mjs`
|
|
29
|
+
|
|
30
|
+
### 展示名
|
|
31
|
+
|
|
32
|
+
- `DSH-GOkifu-compact` → **`dsh-GOkifu-compact`**(前缀小写、只有 GO 大写;包名仍为 `dsh-gokifu-compact`)
|
|
33
|
+
- GitHub 仓库同步改名:`MYCF711/dsh-GOkifu-compact`
|
|
34
|
+
- 修正 `cordis.patch.yml` 里写错的包名(`dsh-chess-context` → `dsh-gokifu-compact`)
|
|
35
|
+
|
|
36
|
+
### 测试
|
|
37
|
+
|
|
38
|
+
118 项单测全绿 + 真实包验证 8/8 + 真实进程 fold 3~6/6
|
|
39
|
+
|
|
40
|
+
## 1.6.3 — 2026-10-29
|
|
41
|
+
|
|
42
|
+
### 真实 DSH 进程里的首次 fold + 修掉「rules 模式从未成功过」的真 bug
|
|
43
|
+
|
|
44
|
+
**新增 `test/real-headless-fold.mjs`**:起一个**真正的 dsh headless 进程**(独立 profile + overlay,
|
|
45
|
+
阈值压到 0.002 触发),跑迷你任务并核对 `compaction/*` 与 checkpoint —— 真 Session、真 compactRegion、
|
|
46
|
+
真 surface 替换。实测 **3~5 次 fold 全成功、0 失败**(`evidence/真实进程首次fold.md`)。
|
|
47
|
+
|
|
48
|
+
**抓到的真 bug**:第一次跑时 7 次 fold 全报
|
|
49
|
+
`session event "compaction/summary" carries non-JSON-serializable data` ——
|
|
50
|
+
官方 `commitCompactionBody()` 把 `summarize()` 返回的 `provider`/`model` **不判空**写进事件,
|
|
51
|
+
而规则摘要(`summaryMode: rules` 与「摘要模型全挂」的兜底)没带这两个字段 ⇒ `provider: undefined` ⇒
|
|
52
|
+
真实 Session 的 JSON 校验拒绝。**`summaryMode: rules` 在真实 DSH 里从未成功过**(假 Session 不校验,
|
|
53
|
+
桌面 preset 又用 hybrid,所以一直没暴露)。
|
|
54
|
+
修法:所有 summarize() 返回路径都带 provider/model 字符串(规则摘要用当前路由做记账口径,
|
|
55
|
+
没有路由用 `chess-context`/`rules` 哨兵)。+harness 断言。
|
|
56
|
+
|
|
57
|
+
### 测试
|
|
58
|
+
|
|
59
|
+
118 项单测 + 真实进程 fold 测试(3 次成功 / 0 失败)
|
|
60
|
+
|
|
61
|
+
## 1.6.2 — 2026-10-29
|
|
62
|
+
|
|
63
|
+
### 压缩永不因摘要模型挂掉而失败(hybrid ⇒ 规则摘要兜底)+ doctor 体检
|
|
64
|
+
|
|
65
|
+
**规则摘要兜底**:`summarize()` 现在三层降级:
|
|
66
|
+
① 配置的摘要模型 → ② 失败就退回「当前路由模型」重试一次(v1.5.1)→ ③ 还不行且 `summaryMode=hybrid`
|
|
67
|
+
就**退回规则摘要(零模型调用)**,fold 必须能落地。压缩失败 = 上下文只增不减,比摘要质量下降严重得多。
|
|
68
|
+
`summaryMode=llm` 不降级(用户明确要模型输出)。+2 harness 用例。
|
|
69
|
+
|
|
70
|
+
**doctor**:新工具 `node test/doctor.mjs` —— 一条命令体检:安装态 / 摘要模型是否在 provider 模型表里 /
|
|
71
|
+
最近压缩成败与错误 / 棋谱健康 / 树新鲜度。本轮实机 131 次压缩失败就是它抓出来的
|
|
72
|
+
(配置里 `magpie/ima/deepseek-v4.1-flash` 不在 provider 模型表)。
|
|
73
|
+
|
|
74
|
+
### 测试
|
|
75
|
+
|
|
76
|
+
118 项全绿
|
|
77
|
+
|
|
78
|
+
## 1.6.1 — 2026-10-29
|
|
79
|
+
|
|
80
|
+
### index.md 每次落盘都刷新(它是模型读的入口)
|
|
81
|
+
|
|
82
|
+
盲测里子代理当场发现 落后于 (350 边/17 失败 vs 447 边/23 失败)——
|
|
83
|
+
因为旧版只在「首次 flush / fold 后」写树。现在 **每次 flush 重写 index.md**(单文件;2000 边实测
|
|
84
|
+
renderIndexMd 3.27ms + 写盘 0.65ms,debounce 后每 1.2s 最多一次), 仍只在首次/fold 后写
|
|
85
|
+
(2000 个文件不能每步来一遍)。+1 harness 用例。
|
|
86
|
+
|
|
87
|
+
### 测试
|
|
88
|
+
|
|
89
|
+
116 项全绿
|
|
90
|
+
|
|
91
|
+
## 1.6.0 — 2026-10-29
|
|
92
|
+
|
|
93
|
+
### goal ③④⑤ 三件收尾
|
|
94
|
+
|
|
95
|
+
**③ `[dead]` 不再是一块永久墓碑**:标记直接从 tewari 参照点取锚点 ——
|
|
96
|
+
`dead retry-if:e384+1`(那条成功边不通了就回头重试);图例同步;
|
|
97
|
+
`blocked:missing-resource` 的图例改成「等它出现,**或者把它创建出来**」。
|
|
98
|
+
|
|
99
|
+
**⑤ 热清单指向**真的**三层树**:旧省略行写的是 `graph.md`,而它从 v1.2.2 起就不再自动写了(死指针)。
|
|
100
|
+
现在引擎把会话树目录传进渲染器,输出 `TRACE: <sessions>/<sid>/index.md (per-node detail: nodes/<id>.md)`。
|
|
101
|
+
**盲测 2/2**:两个隔离子代理(只给清单、不提读文件)都自己读了 index.md / graph.json / nodes/*.md,
|
|
102
|
+
并把清单里被省略的 13 条失败做法逐条重建;其中一个还发现 index.md 已过期、改用 graph.json 作权威。
|
|
103
|
+
|
|
104
|
+
**④ 历史误报回洗**:新工具 `test/rewash-graph.mjs`(dry-run 默认、写前备份、会话在写则拒绝、证据对齐校验)。
|
|
105
|
+
对 `session-5acafe42` 执行 `--apply`:failure 边 101 → **71**,`text` 型误报 43 → **8**(剩下 8 条证据对不上,保守不动),
|
|
106
|
+
其中 4 条改判 `hard-error`(原文确有错误)、30 条降级 `unverified`;35 条留 `rewashed` 审计字段;树已重建。
|
|
107
|
+
|
|
108
|
+
证据:`evidence/收尾三件-dead锚点-树读取-回洗.md`
|
|
109
|
+
|
|
110
|
+
### 测试
|
|
111
|
+
|
|
112
|
+
115 项全绿(+4 errorSnippet 回归、+2 标记契约)
|
|
113
|
+
|
|
114
|
+
## 1.5.1 — 2026-10-29
|
|
115
|
+
|
|
116
|
+
### 真实计费核对 + 摘要模型失效兜底(实机数据驱动)
|
|
117
|
+
|
|
118
|
+
**1. 真实计费核对(`evidence/真实计费核对.md`)** —— 用会话日志里每次请求的真实 usage 拆账:
|
|
119
|
+
|
|
120
|
+
| 会话 | 请求 | prompt tokens | 缓存命中率 | 清单占 prompt | 其中陈旧副本 |
|
|
121
|
+
|---|---:|---:|---:|---:|---:|
|
|
122
|
+
| session-5acafe42 | 653 | 258,330,390 | 94.5% | **21.3%** | **54.4M token** |
|
|
123
|
+
| session-5787ac6b | 429 | 194,031,958 | 94.7% | 2.7% | 5.1M |
|
|
124
|
+
| session-e16faf2b(当前) | 348 | 93,691,039 | 97.0% | **0.2%** | 0.13M |
|
|
125
|
+
|
|
126
|
+
三条结论:① 真实 prompt 缓存吃掉 94~97% ⇒「省 token」≠「省钱」;② 旧版热清单是那个会话里**最大的浪费源**
|
|
127
|
+
(21.3%,其中 98.9% 是陈旧副本,v1.5.0 已消除);③ fold 真实成功率 3/226、1/51 ⇒ 模拟的
|
|
128
|
+
「省 22.7%–43.3%」在实机上从未发生。
|
|
129
|
+
|
|
130
|
+
**2. 摘要模型失效兜底(实机 8 次失败暴露)**:当前会话超过阈值后连续 8 次压缩全部报
|
|
131
|
+
`pi-ai provider "magpie" has no configured model "ima/deepseek-v4.1-flash"` ——
|
|
132
|
+
插件 patch 与 preset 把摘要模型写成 magpie/ima,而 magpie provider 的模型表里没有它。
|
|
133
|
+
|
|
134
|
+
- 引擎:`summarize()` 在显式配置的摘要模型失败时**退回当前路由模型重试一次**(只一次;
|
|
135
|
+
与路由相同则照旧抛错)。现有 harness 用例 2 条。
|
|
136
|
+
- 配置:插件自带 `cordis.patch.yml` 与**已安装** preset 的摘要模型改为留空(跟随路由);
|
|
137
|
+
安装态备份 `cordis.patch.yml.bak-before-summarizer-fix-1793213214`。
|
|
138
|
+
- 新工具:`test/measure-billing.mjs`(真实 usage 审计;解压多帧 zstd 依赖本机 python + zstandard)。
|
|
139
|
+
|
|
140
|
+
### 测试
|
|
141
|
+
|
|
142
|
+
109 项全绿(+2 摘要回落用例)
|
|
143
|
+
|
|
144
|
+
## 1.5.0 — 2026-10-29
|
|
145
|
+
|
|
146
|
+
### P1-4 彻底修法:热清单**就地替换**,surface 永远只有一条
|
|
147
|
+
|
|
148
|
+
**问题(拿真实会话日志数出来的)**:旧版每次注入都**追加**一条新 `user/message`,旧的不替换。
|
|
149
|
+
`session-5acafe42`(死循环那个会话)累积 **176 条 / 809,819 字符 ≈ 27 万 token** ——
|
|
150
|
+
它的上下文峰值 672,392 token 里,约 27 万是**这个插件自己注入的热清单**。
|
|
151
|
+
一个压缩插件自己的热上下文成了最大的上下文消费者。
|
|
152
|
+
|
|
153
|
+
| 会话 | 注入条数 | 累计字符 | ≈ tokens |
|
|
154
|
+
|---|---:|---:|---:|
|
|
155
|
+
| `session-5acafe42` | 176 | 809,819 | ≈ 270,000 |
|
|
156
|
+
| `session-365cdcf6` | 103 | 238,083 | ≈ 79,000 |
|
|
157
|
+
| `session-5787ac6b` | 74 | 155,569 | ≈ 52,000 |
|
|
158
|
+
| 12 个会话合计 | 375 | 1,225,074 | ≈ 408,000 |
|
|
159
|
+
|
|
160
|
+
**改法**:`pre-step` 里找到当前 surface 上最后一条 `chess-context` 节点,用 DSH 官方的
|
|
161
|
+
`surfaceOp: {op:"replace", startSeq, endSeq}` + `sourceEventSeqs` **就地替换**(官方 system-prompt
|
|
162
|
+
的 in-history 提交、`tool-result-pruner` 用的同一机制),并且**不进** `decision.messages`。
|
|
163
|
+
首次注入(或清单被 fold 遮蔽)时仍走追加路径。
|
|
164
|
+
|
|
165
|
+
- 内容一字不差时直接返回:不写日志、不推进 `contentGeneration`
|
|
166
|
+
- 锚点失效(刚被 fold 遮蔽)会抛错 ⇒ **捕获后退回追加**,绝不因此丢信息
|
|
167
|
+
- 被 fold 遮蔽后**立刻补回**,不等限流(否则模型一段时间内看不到死路清单)
|
|
168
|
+
- 限流维持原样(≥40 事件 / 失败边 +5)—— 替换不占额外 prompt,但会写日志事件并推进
|
|
169
|
+
`contentGeneration`(下游 `startsSeries`),节奏不动最稳
|
|
170
|
+
- 新增配置 `hotLedgerReplace`(默认 `true`,false 退回追加)
|
|
171
|
+
- **历史包袱一次清**:v1.5.0 之前追加出来的旧清单不能被删除(surface 只有 append/replace),
|
|
172
|
+
但可以逐条**替换成一行占位**(`[stale chess-ledger elided …]`)。实测 `session-5acafe42` 的 surface 上
|
|
173
|
+
还压着 **44 条 / 295,255 字符 ≈ 9.8 万 token** —— 那个会话下次被打开时会被自动清掉。
|
|
174
|
+
幂等:占位本身 < 200 字符,下次进来直接跳过。
|
|
175
|
+
|
|
176
|
+
**验证**
|
|
177
|
+
|
|
178
|
+
- `test/real-ledger-replace.mjs`(新,8/8):真实 `@deepseek-ai/dsh-session` 上验证替换机制 ——
|
|
179
|
+
含「连续替换 50 次仍只有一条」「替换非当前节点抛错」「漏报 sourceEventSeqs 抛错」「替换后仍能按
|
|
180
|
+
`source.kind` 找回当前清单」
|
|
181
|
+
- `test/engine-harness.test.mjs`(+3):就地替换(`decision.messages` 无新增、surface 恒 1 条、内容更新)、
|
|
182
|
+
被 fold 遮蔽后立刻补回、历史旧清单被换成占位且幂等;变异自检(关掉替换 / 关掉清理 ⇒ 用例变红)
|
|
183
|
+
- `node test/run.mjs` → **107 passed, 0 failed**;verify-install 13/13;real-modules 4/4;real-fold 5/5
|
|
184
|
+
|
|
185
|
+
产物:`evidence/P1-4-清单替换实测.md`
|
|
186
|
+
|
|
187
|
+
**遗留**:历史累积要等下一次 fold 才会被遮蔽(surface 只有 append/replace,无法删除节点);
|
|
188
|
+
本机运行实例需**再重启一次**才带上本改动。
|
|
189
|
+
|
|
190
|
+
## 1.4.0 — 2026-10-29
|
|
191
|
+
|
|
192
|
+
### 模型消费者视角:标记必须自解释、原因不许丢(子代理盲测驱动)
|
|
193
|
+
|
|
194
|
+
**三处实测缺陷**(都不是结构问题,是「写进去的内容不够模型用」):
|
|
195
|
+
|
|
196
|
+
1. **标记裸奔**:图例被绑在「检测到手割」上 ⇒ 一个只有 EACCES 失败、没有成功路径的会话里
|
|
197
|
+
`[blocked]` 出现了却没有任何解释;而 `redundant` / `longer` 真的会出现在清单里,
|
|
198
|
+
图例里**从来没有**它们。
|
|
199
|
+
2. **标记是缩写,不是语义**:`[blocked]` 说不出「什么被挡住了、什么条件变了能再试」——
|
|
200
|
+
而那正是 1.1.0 设计三态时给出的理由(`revisit_if`)。现在写成 `[blocked:permission]`。
|
|
201
|
+
3. **原因失踪**:旧版 level ≥3 直接把 `→ 报错原文` 整段砍掉 ⇒ 全库 133 条可见失败边里只有
|
|
202
|
+
**25 条**带原因。而盲测里 **12/12 次回答**都引用了报错原文 —— 它是模型判断「是不是同一个坑」的判据。
|
|
203
|
+
|
|
204
|
+
**改动**
|
|
205
|
+
|
|
206
|
+
- `src/ledger.mjs`:`failureTags()` + `MARKER_LEGEND` + `legendKey()`;图例**按用到的标记动态生成**
|
|
207
|
+
(出现即解释);`renderFailureLine()` 任何档位都保留原因(`[90,60,36,25]` 逐档变短);
|
|
208
|
+
手割分析改为**只算一次**(尾部 30 条,旧版放在档位循环里重复 6 次,且显示条数 >30 时一条都不算);
|
|
209
|
+
新增档位预判:**注定装不下的级别直接跳过**(2000 边渲染 7.58 ms → **0.478 ms**)
|
|
210
|
+
- `src/engine.mjs`:新增配置 `hotLedgerMarkers: semantic | terse | off`(默认 `semantic`)
|
|
211
|
+
- `test/markers.test.mjs`(新,9 项):标记裸奔、图例动态生成、`redundant`/`longer` 图例、
|
|
212
|
+
多参照点、>30 条失败边仍有手割、原因在任何档位都在、三档位行为
|
|
213
|
+
- `test/ab-render.mjs`(新):A/B 夹具 —— 同一张棋谱三种档位各渲染一份,两个场景(基本 / 误导)
|
|
214
|
+
- `test/engine-harness.test.mjs`:新增「标记档位一路传到热清单」用例(非法档位回落 `semantic`)
|
|
215
|
+
- `docs/最终报告.md` / `docs/性能与成本.md` / `README.md` / `docs/计划表.md`:数字与示例同步
|
|
216
|
+
|
|
217
|
+
**盲测结果(`evidence/热清单标记AB实验.md`)**
|
|
218
|
+
|
|
219
|
+
| 实验 | 结果 |
|
|
220
|
+
|---|---|
|
|
221
|
+
| ① 报错原文已说清该怎么做(3 臂 × 3 样本) | **8/8 满分,三臂无差别**(与 1.1.0 三态 A/B 的「差异为零」一致) |
|
|
222
|
+
| ② 报错原文**误导**(2 臂 × 6 样本) | 带标记 **0/6** 重试等价死路;不带标记 **1/6** 重试(理由:「SIGKILL 是外部中止,不是否定性证据」) |
|
|
223
|
+
| 引用率 | 带标记 6/6 次回答引用了 `dead`/`redundant`;不带标记只能引报错原文 |
|
|
224
|
+
|
|
225
|
+
方向性证据(n=6,不显著):标记只在**报错原文误导**时有价值;默认保留 `semantic`,预算敏感可关。
|
|
226
|
+
|
|
227
|
+
**全库代价(45 个真实会话同语料新旧对比)**:tokens 19,267 → 20,579(**+6.8%**),
|
|
228
|
+
带原因的失败边 89 → **209(2.35×)**,平均档位 L1.40 → L1.42。
|
|
229
|
+
|
|
230
|
+
### 测试
|
|
231
|
+
|
|
232
|
+
104 项全绿(原 94 + 新增 10);`bench-2000.json`:323 tokens / 0.478 ms
|
|
233
|
+
|
|
234
|
+
## 1.3.5 — 2026-10-28
|
|
235
|
+
|
|
236
|
+
### P0 修复:`worldHash` 类型契约(事故:压缩 226 次只成功 3 次 → 上下文涨到 66 万 → 模型死循环)
|
|
237
|
+
|
|
238
|
+
**根因**:`worldstate.hash()` 返回 `{ hash, mode, files }` 对象,engine 的 `worldHashOf()`
|
|
239
|
+
把它原样交给 keeper,节点字段于是存了**对象**;随后 `renderFacts()` 里
|
|
240
|
+
`latest?.worldHash?.slice(0, 12)` 对对象调 `.slice()` 抛
|
|
241
|
+
`latest?.worldHash?.slice is not a function` —— 这一步在 `summarize()` 之前,
|
|
242
|
+
于是 `compactRegion` 事务整体回滚,**压缩彻底不工作**。
|
|
243
|
+
|
|
244
|
+
**改动**
|
|
245
|
+
|
|
246
|
+
- `src/engine.mjs`:`worldHashOf()` 收敛成字符串(兼容 `string` / `{hash}` / `pending`);
|
|
247
|
+
`constraintHashOf()` 改为 `hashSet(collectConstraintText(g))`(`st.constraints` 从未被赋值
|
|
248
|
+
⇒ `constraintHash` 恒为 `pending` ⇒ `stateIndex` 永不建立、置换检测形同虚设)
|
|
249
|
+
- `src/graph.mjs`:新增 `hashText()`;`addAgentNode()` 入口归一化(对象永不进图);
|
|
250
|
+
`fromJSON()` 在加载边界修复历史脏数据(对象 → 字符串、按时序回填 pending `constraintHash`)
|
|
251
|
+
并**无条件重建 `stateIndex`**(派生数据不信任磁盘旧值)
|
|
252
|
+
- `src/ledger.mjs`:新增 `shortHash()` 防御层,`CURRENT_STATE_KEY` 不再裸调 `.slice()`
|
|
253
|
+
|
|
254
|
+
**验证**
|
|
255
|
+
|
|
256
|
+
- `node test/run.mjs` → **94 passed, 0 failed**(87 + 新增 7)
|
|
257
|
+
- 全库回放(新增工具 `node test/verify-graphs.mjs`):23 个会话 / 1578 个 agent 节点 /
|
|
258
|
+
对象 worldHash **1279 → 0** / `stateIndex` **5 → 185** / 全部会话 `renderFacts`+`renderLedger` 不抛错
|
|
259
|
+
- 真实日志独立核对:`session-5acafe42` 的 `compaction/end` **226** 次、`error` **223** 次、
|
|
260
|
+
其中本错误 **139** 次
|
|
261
|
+
- 变异自检:把修复回滚 → 新增的端到端回归变红(两层都回滚时错误与实机同形)
|
|
262
|
+
- 干净 HEAD 克隆 + `git apply` 补丁 → 94 passed(不是改着源码跑的自证)
|
|
263
|
+
|
|
264
|
+
**产物**:`docs/P0-worldhash-死循环-根因与修复方案.md`、`docs/P0-worldhash-死循环修复.patch`、
|
|
265
|
+
`evidence/P0-worldhash-修复验证.md`、`test/worldhash.test.mjs`、`test/verify-graphs.mjs`
|
|
266
|
+
|
|
267
|
+
**部署**:插件在 DSH 启动时加载,**需重启生效**;历史数据由 `fromJSON` 加载边界自动修复,
|
|
268
|
+
无需手工迁移。
|
|
269
|
+
|
|
270
|
+
## 1.3.4 — 2026-10-28
|
|
271
|
+
|
|
272
|
+
### 文档数字同步到 v1.3.1
|
|
273
|
+
|
|
274
|
+
- `docs/性能与成本.md`:476 → **310 tokens**(注明 v1.2.x 时 476)
|
|
275
|
+
- `docs/最终报告.md`:结论段与性能表同步
|
|
276
|
+
- `docs/计划表.md` M11:310 tokens / 81K 事实块 / 1.3ms md
|
|
277
|
+
|
|
278
|
+
### 测试
|
|
279
|
+
|
|
280
|
+
87 项全绿
|
|
281
|
+
|
|
282
|
+
## 1.3.3 — 2026-10-28
|
|
283
|
+
|
|
284
|
+
### 文档:新增 `docs/三层树设计.md`
|
|
285
|
+
|
|
286
|
+
- 为什么是「缩进树 + 扁平节点」的混合(DAG 最大入度 119,不能目录嵌套)
|
|
287
|
+
- 每层的作用与消费者
|
|
288
|
+
- **6 个实测缺陷**的完整记录(子代理驱动,v1.2.6 → v1.3.0)
|
|
289
|
+
- **3 条核心教训**(结构 ≠ 内容 / 不改运行中的数据 / SGF 树 vs DAG)
|
|
290
|
+
- 性能数据(253 节点 ~150ms)
|
|
291
|
+
|
|
292
|
+
### 测试
|
|
293
|
+
|
|
294
|
+
87 项全绿
|
|
295
|
+
|
|
296
|
+
## 1.3.2 — 2026-10-28
|
|
297
|
+
|
|
298
|
+
### 文档:最终报告加 v1.x 章节
|
|
299
|
+
|
|
300
|
+
- 6 个版本的变更表(1.2.6 → 1.3.1)
|
|
301
|
+
- 3 条核心教训:结构 ≠ 内容 / 不改运行中的数据 / SGF 树 vs DAG
|
|
302
|
+
- 实测数据对比:热上下文 476→310、节点 200→242、评语 7→162、死链 230→0
|
|
303
|
+
|
|
304
|
+
### 测试
|
|
305
|
+
|
|
306
|
+
87 项全绿
|
|
307
|
+
|
|
308
|
+
## 1.3.1 — 2026-10-28
|
|
309
|
+
|
|
310
|
+
### 热清单省预算:短标签 + L4 条数 50 → 20
|
|
311
|
+
|
|
312
|
+
**问题**:v1.3.0 加了 `[text:?]` / `[verify:kind]` / 三态完整标签(`[dead:a-working-path-avoids-it revisit_if=...]`),
|
|
313
|
+
2000 边场景热清单从 L4 降到 **L5**(只显示 10 条)。
|
|
314
|
+
|
|
315
|
+
**改法**:
|
|
316
|
+
|
|
317
|
+
1. 热清单用**短标签**(`[dead]` / `[blocked]` / `[failed]`),详细版留 `index.md`
|
|
318
|
+
2. `tailFailures` 从 50 → **20**
|
|
319
|
+
|
|
320
|
+
**实测**:2000 边 → 热上下文 **310 tokens / L4**(之前 276 / L5、476 / L4)
|
|
321
|
+
|
|
322
|
+
### 测试
|
|
323
|
+
|
|
324
|
+
87 项全绿
|
|
325
|
+
|
|
326
|
+
## 1.3.0 — 2026-10-28
|
|
327
|
+
|
|
328
|
+
### text 型 failure 标记 `[text:?]`(渲染层,不改数据)
|
|
329
|
+
|
|
330
|
+
**问题**:真实会话的 101 条 failure 里 43 条是 `verify.kind === "text"` —— 其中大量是假阳性(`get_goal`/`update_goal` 的合法 JSON、skill 列表、markdown 被当成失败)。
|
|
331
|
+
|
|
332
|
+
**为什么不在数据层回洗**:真实会话在跑,`#flush` 会覆盖 `graph.json`(实测:回洗 5 条后立刻被覆盖)。
|
|
333
|
+
|
|
334
|
+
**改法**:渲染层标记 —— `renderNodeMd` 和 `index.md` 的 text 型 failure 加 `[text:?]`,提示模型「这个判定不可靠,看原因自己判断」。
|
|
335
|
+
|
|
336
|
+
### 实测
|
|
337
|
+
|
|
338
|
+
- **47 条** text 型 failure 现在带 `[text:?]`
|
|
339
|
+
- 数据层不动(避免与运行中的会话冲突)
|
|
340
|
+
|
|
341
|
+
### 测试
|
|
342
|
+
|
|
343
|
+
87 项全绿
|
|
344
|
+
|
|
345
|
+
## 1.2.9 — 2026-10-28
|
|
346
|
+
|
|
347
|
+
### 修三层树的死链与计数(第二个子代理实测)
|
|
348
|
+
|
|
349
|
+
| 问题 | 修法 |
|
|
350
|
+
|---|---|
|
|
351
|
+
| **`raw/` 死链**:v1.2.4 砍掉 raw 但节点里还写 `../raw/<seq>.md`(230 个节点全是死链) | 改成「(raw/ 已砍掉:节点数据在 graph.json)」 |
|
|
352
|
+
| **计数不一致**:index 用 `g.order.length`,graph.json 是 `g.nodes` 数量(227 vs 229) | 改用 `Object.keys(g.nodes).length` |
|
|
353
|
+
| **评语不是 LLM 原话**:165 份「评语(来自入边)」只是把 action 抄一遍 | 标注「(非 LLM 原话)」 |
|
|
354
|
+
|
|
355
|
+
### 实测
|
|
356
|
+
|
|
357
|
+
- 死链:**0 个**(之前 230 个全是)
|
|
358
|
+
- index 计数:**235**(= `g.nodes`,与 graph.json 一致)
|
|
359
|
+
- 评语标注:**170 个**节点带「非 LLM 原话」
|
|
360
|
+
|
|
361
|
+
### 测试
|
|
362
|
+
|
|
363
|
+
87 项全绿
|
|
364
|
+
|
|
365
|
+
## 1.2.8 — 2026-10-28
|
|
366
|
+
|
|
367
|
+
### 缺陷 6:读时重建不一致
|
|
368
|
+
|
|
369
|
+
**问题**:`graph.json` / `index.md` / `nodes/` 三个来源在写入过程中不一致(边读边写)。
|
|
370
|
+
|
|
371
|
+
**修法**:
|
|
372
|
+
|
|
373
|
+
1. **写入顺序**:先写 `nodes/` + `index.md`,**最后**写 `graph.json`(原子 rename = 提交点)
|
|
374
|
+
2. **版本标记**:`index.md` 头部写 `> updated: <ISO>`(与 `graph.json` 的 `updatedAt` 同源),读者可对比
|
|
375
|
+
|
|
376
|
+
**注意**:Windows 不支持目录原子 rename,所以不是完全原子 —— 但 `graph.json` 的 rename 是提交点,读者以它为准。
|
|
377
|
+
|
|
378
|
+
### 测试
|
|
379
|
+
|
|
380
|
+
87 项全绿
|
|
381
|
+
|
|
382
|
+
## 1.2.7 — 2026-10-28
|
|
383
|
+
|
|
384
|
+
### 三层树补缺陷 2 & 5(子代理实测驱动)
|
|
385
|
+
|
|
386
|
+
| # | 缺陷 | 修法 |
|
|
387
|
+
|---|---|---|
|
|
388
|
+
| 2 | **意图缺失**:200 节点只有 7 个有 `goal`,边无 `intent` | `renderNodeMd` 的「评语」段加兜底:`goal` 为空时用**入边的 `intent`**,再为空用**入边的 `action`** |
|
|
389
|
+
| 5 | **标签不可信**:43/98 是 verifier 误报(`text` 型) | `renderNodeMd` / `index.md` 的失败边都带 `[verify:kind]`(`exit` / `host-error` / `text` / `none`),模型能区分「真失败」和「文本误报」 |
|
|
390
|
+
|
|
391
|
+
### 实测
|
|
392
|
+
|
|
393
|
+
- 评语兜底:**162 个节点**现在有评语(之前只有 7 个)
|
|
394
|
+
- verify 标签:**101 条**失败边带 `[verify:kind]`
|
|
395
|
+
|
|
396
|
+
### 测试
|
|
397
|
+
|
|
398
|
+
87 项全绿
|
|
399
|
+
|
|
400
|
+
## 1.2.6 — 2026-10-28
|
|
401
|
+
|
|
402
|
+
### 三层树补三处缺陷(子代理实测驱动)
|
|
403
|
+
|
|
404
|
+
一个隔离子代理只靠三层树回答「这个会话试过哪些失败路径」,报了 6 个缺陷,其中 **3 个是实现问题**:
|
|
405
|
+
|
|
406
|
+
| # | 缺陷 | 修法 |
|
|
407
|
+
|---|---|---|
|
|
408
|
+
| 1 | **原因**缺失:98 条 failure 只有 13 条带附注 | `renderNodeMd` 出边的 `errorSnippet` 截断 100 → **400** |
|
|
409
|
+
| 3 | **节点缺失**:`#flush` / `build-tree` 只写 `g.order`,被合并且仍被边引用的节点没文件 | 改成写**所有** `g.nodes` |
|
|
410
|
+
| 4 | **index 只列 190/404 条边**:缩进树每节点只出现一次,跨边/置换边不在 | 加「**失败边全表**」段(含跨边) |
|
|
411
|
+
|
|
412
|
+
### 实测
|
|
413
|
+
|
|
414
|
+
- `index.md` 21KB → **54.6KB**,含全部失败边(id / from → to / 意图 / 错误原文 160 字符)
|
|
415
|
+
- `nodes/` **224 个**(含被合并且仍被边引用的)
|
|
416
|
+
- `build-tree.mjs` 不再写 `raw/`(v1.2.4 砍掉后残留的代码)
|
|
417
|
+
|
|
418
|
+
### 未修(记录在 HANDOFF)
|
|
419
|
+
|
|
420
|
+
- 标签不可信(43/98 是 verifier 误报)—— 旧数据,新代码已修(v0.1.2)
|
|
421
|
+
- 读时重建不一致 —— 边读边写,任何计数要带时间戳
|
|
422
|
+
|
|
423
|
+
### 测试
|
|
424
|
+
|
|
425
|
+
87 项全绿
|
|
426
|
+
|
|
427
|
+
## 1.2.5 — 2026-10-28
|
|
428
|
+
|
|
429
|
+
### `index.md` 改缩进树(每节点只出现一次)
|
|
430
|
+
|
|
431
|
+
`index.md` 从平铺改成按深度的缩进树:
|
|
432
|
+
|
|
433
|
+
- 缩进 = 从**入度为 0 的节点**出发的最短路径深度(封顶 12 级)
|
|
434
|
+
- 每个节点只出现一次
|
|
435
|
+
- 出边挂在节点下一行
|
|
436
|
+
|
|
437
|
+
**实测输出**:
|
|
438
|
+
|
|
439
|
+
```markdown
|
|
440
|
+
- [n1](./nodes/n1.md) USER seq=968 我重启了...
|
|
441
|
+
- [n2](./nodes/n2.md) USER seq=969 <hindsight_knowledge>...
|
|
442
|
+
- e1 ✗ get_goal
|
|
443
|
+
- [n12](./nodes/n12.md) USER seq=1042 持续优化...
|
|
444
|
+
- [n59](./nodes/n59.md) STATE seq=1363 (无目标)
|
|
445
|
+
- e66 ✗ edit(file_path=...
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### 为什么不做目录嵌套(用户提议过)
|
|
449
|
+
|
|
450
|
+
真实数据:203 节点 / 396 边,**多父节点 7 个,最大入度 119**(n174 有 119 个父),transposition 边占 61%。
|
|
451
|
+
|
|
452
|
+
嵌套会让 n174 在 119 个目录里重复 → 文件爆炸 + 不同步。**棋谱是 DAG,不是树** —— 缩进树只表达深度,不复制节点。
|
|
453
|
+
|
|
454
|
+
### 测试
|
|
455
|
+
|
|
456
|
+
87 项全绿
|
|
457
|
+
|
|
458
|
+
## 1.2.4 — 2026-10-28
|
|
459
|
+
|
|
460
|
+
### 砍掉 `raw/`(节点 JSON 与 `graph.json` 重复)
|
|
461
|
+
|
|
462
|
+
三层文件树的 `raw/` 存的是**节点 JSON**,和 `graph.json` 完全重复(200 文件 / 430KB)。
|
|
463
|
+
真正的「原始记录」应该是**事件原文**,不是节点 JSON —— 这个以后从 session 日志接。
|
|
464
|
+
|
|
465
|
+
**改动**:
|
|
466
|
+
|
|
467
|
+
- `#flush` / `build-tree.mjs` 不再写 `raw/`
|
|
468
|
+
- 三层变两层:`index.md` + `nodes/*.md`(+ `graph.json` 数据源)
|
|
469
|
+
|
|
470
|
+
**省**:430KB / 200 文件。
|
|
471
|
+
|
|
472
|
+
### 测试
|
|
473
|
+
|
|
474
|
+
87 项全绿
|
|
475
|
+
|
|
476
|
+
## 1.2.3 — 2026-10-28
|
|
477
|
+
|
|
478
|
+
### 展示名改为 `DSH-GOkifu-compact`(大写 GO)
|
|
479
|
+
|
|
480
|
+
`GO` 才是围棋(`go` 是编程语言)。但 **npm 包名只能小写**(`dsh-gokifu-compact`),这是 npm 的硬限制。
|
|
481
|
+
|
|
482
|
+
- README / AGENTS / QUICKSTART / docs 标题:`DSH-GOkifu-compact`
|
|
483
|
+
- GitHub 仓库:`MYCF711/DSH-GOkifu-compact`
|
|
484
|
+
- npm 包名 / 配置项 / 路径:保持 `dsh-gokifu-compact`(小写)
|
|
485
|
+
|
|
486
|
+
### 测试
|
|
487
|
+
|
|
488
|
+
87 项全绿
|
|
489
|
+
|
|
490
|
+
## 1.2.2 — 2026-10-28
|
|
491
|
+
|
|
492
|
+
### 性能:`graph.md` 不再自动写
|
|
493
|
+
|
|
494
|
+
`graph.md` 是整篇人读视图(157KB),每次 flush 写是纯 IO 浪费;三层文件树(index/nodes/raw)已经是人读视图。
|
|
495
|
+
|
|
496
|
+
**改法**:
|
|
497
|
+
|
|
498
|
+
- `#flush` 不再写 `graph.md`
|
|
499
|
+
- 需要时:`node test/build-md.mjs <sessionDir>` 按需生成
|
|
500
|
+
|
|
501
|
+
**保留**:`graph.json`(数据源,插件自己恢复用,必须写)。
|
|
502
|
+
|
|
503
|
+
### 测试
|
|
504
|
+
|
|
505
|
+
87 项全绿
|
|
506
|
+
|
|
507
|
+
## 1.2.1 — 2026-10-28
|
|
508
|
+
|
|
509
|
+
### 文档:README 加三层文件树说明
|
|
510
|
+
|
|
511
|
+
把 `index.md` / `nodes/*.md` / `raw/*.md` 三层的作用与消费者写清楚了。
|
|
512
|
+
|
|
513
|
+
### 工具:`test/build-tree.mjs`
|
|
514
|
+
|
|
515
|
+
给 v1.2.0 之前已有的会话补三层文件树(从 `graph.json` 生成)。
|
|
516
|
+
实测:`session-5acafe42` 补了 **183 个节点**。
|
|
517
|
+
|
|
518
|
+
### 测试
|
|
519
|
+
|
|
520
|
+
87 项全绿
|
|
521
|
+
|
|
522
|
+
## 1.2.0 — 2026-10-28
|
|
523
|
+
|
|
524
|
+
### 三层文件树(index / nodes / raw)
|
|
525
|
+
|
|
526
|
+
**问题**:`graph.md` 是整篇 177KB,人无法浏览,模型无法按需加载。
|
|
527
|
+
|
|
528
|
+
**改法**:每次 flush 额外写三层:
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
sessions/<id>/
|
|
532
|
+
├── index.md 落子顺序(每个节点一行 + 出边状态)
|
|
533
|
+
├── nodes/n1.md 单节点:评语 / 状态 / 入边 / 出边 / raw 链接
|
|
534
|
+
├── raw/1.md 原始记录(节点 JSON 全文)
|
|
535
|
+
└── graph.json / graph.md (保留兼容)
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**index.md**:
|
|
539
|
+
|
|
540
|
+
```markdown
|
|
541
|
+
- [n1](./nodes/n1.md) USER seq=1 目标:把构建跑通
|
|
542
|
+
- e1 ✓ 跑 npm install
|
|
543
|
+
- [n2](./nodes/n2.md) STATE seq=2 装依赖
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
**nodes/n2.md**:
|
|
547
|
+
|
|
548
|
+
```markdown
|
|
549
|
+
# n2 · AGENT seq=2
|
|
550
|
+
## 评语(LLM 当时的目标)
|
|
551
|
+
装依赖
|
|
552
|
+
## 状态
|
|
553
|
+
- worldHash: `W1`
|
|
554
|
+
- constraintHash: `C1`
|
|
555
|
+
## 入边
|
|
556
|
+
- e1 ← n1: 跑 npm install [success]
|
|
557
|
+
## 出边
|
|
558
|
+
(无)
|
|
559
|
+
## 原始记录
|
|
560
|
+
../raw/2.md
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**设计依据**:`evidence/棋谱有效性实验.md` —— 干净子代理实验证明三层缺一不可:
|
|
564
|
+
索引让模型看到全部死路,节点给详情,原始补抽取的漏。
|
|
565
|
+
|
|
566
|
+
### 测试
|
|
567
|
+
|
|
568
|
+
**87 项**(+2:index.md / 单节点 md)
|
|
569
|
+
|
|
570
|
+
## 1.1.0 — 2026-10-28
|
|
571
|
+
|
|
572
|
+
### 失败三态(子代理 A/B 实验驱动)
|
|
573
|
+
|
|
574
|
+
**实验结论**:两个隔离子代理独立做 A/B(带标记 vs 不带),**行为差异为零**。
|
|
575
|
+
`[dead]` 作为「别重试」的指令没用 —— 失败记录 + `WORKING` 行已经足够推出;
|
|
576
|
+
而且**有损**:把「相对于当前成功路径」写成永久墓碑,会关掉「权限变了本来能走」的路。
|
|
577
|
+
|
|
578
|
+
**改法**:`failureClass(edge, tewari)` 返回三态:
|
|
579
|
+
|
|
580
|
+
| 状态 | 条件 | 带什么 |
|
|
581
|
+
|---|---|---|
|
|
582
|
+
| `blocked` | 资源类错误(EACCES / ENOENT / timeout / ECONNREFUSED) | `revisit_if=...`(什么条件变了可以再试) |
|
|
583
|
+
| `dead` | 有成功路径且**失败边有终点**证明不经过它 | `revisit_if=working path fails` + `redundant:<edge>` |
|
|
584
|
+
| `failed` | 其余(可重试性未知) | 无 |
|
|
585
|
+
|
|
586
|
+
**关键顺序**:先判 `blocked` 再判 `dead` —— 权限不足是环境性阻塞,不是本质无解。
|
|
587
|
+
|
|
588
|
+
**关键边界**:`to` 为 null(没走到任何节点)**不算 dead 证据** —— 只说明试过没成,不能证明有替代。
|
|
589
|
+
|
|
590
|
+
**实测输出**:
|
|
591
|
+
|
|
592
|
+
```
|
|
593
|
+
LEARNED (3 failed attempts):
|
|
594
|
+
# dead=a working path avoids it (revisit_if it fails) | blocked=needs a resource (revisit_if it changes) | failed=retryability unknown | novel=explored states no working path covered
|
|
595
|
+
- e2 "绕路到B" → boom [dead:a-working-path-avoids-it revisit_if=working path fails redundant:e1]
|
|
596
|
+
- e3 "写 prod" → EACCES [blocked:permission revisit_if=permission changes]
|
|
597
|
+
- e4 "试命令" → boom [failed:retryability unknown]
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### 测试
|
|
601
|
+
|
|
602
|
+
85 项全绿
|
|
603
|
+
|
|
604
|
+
## 1.0.0 — 2026-10-28
|
|
605
|
+
|
|
606
|
+
### 手割多参照点(Multi-baseline tewari)
|
|
607
|
+
|
|
608
|
+
**问题**:之前取成功路径的并集,同一条失败边只能给一个结论。
|
|
609
|
+
但「看第二个你判断优,看第三个是劣」—— 同一条失败边相对不同成功路径可能有不同结论。
|
|
610
|
+
|
|
611
|
+
**改法**:`tewariAnalysis` 对**每条**成功出边单独判定,返回:
|
|
612
|
+
|
|
613
|
+
```js
|
|
614
|
+
{
|
|
615
|
+
baselines: [
|
|
616
|
+
{ edgeId: "e1", sameEndpoint: true, reachesEndpoint: true },
|
|
617
|
+
{ edgeId: "e2", sameEndpoint: false, reachesEndpoint: false },
|
|
618
|
+
],
|
|
619
|
+
redundantVs: ["e1"], // 相对哪些成功路径是冗余(同终点)
|
|
620
|
+
longerVs: [], // 相对哪些绕路
|
|
621
|
+
probes: [...], // 探出的新节点
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
热清单显示:
|
|
626
|
+
|
|
627
|
+
```
|
|
628
|
+
- e3 "绕到B" → boom [redundant vs e1]
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
**1.0.0 含义**:API 稳定、语义完整(同型 / 探新 / 冗余 / 绕路,每条边明确指向「相对哪条成功路径」)。
|
|
632
|
+
|
|
633
|
+
### 测试
|
|
634
|
+
|
|
635
|
+
85 项全绿
|
|
636
|
+
|
|
637
|
+
## 0.9.1 — 2026-10-28
|
|
638
|
+
|
|
639
|
+
### 热清单去重:`CURRENT PATH` 与 `WORKING` 相同时只显示一个
|
|
640
|
+
|
|
641
|
+
之前两个都显示(一个含失败边,一个只有成功边),模型会困惑。
|
|
642
|
+
现在:如果当前路径 == 成功路径,只显示 `WORKING`;不同才额外显示 `CURRENT PATH`。
|
|
643
|
+
|
|
644
|
+
### 文档:README 加围棋术语对照表
|
|
645
|
+
|
|
646
|
+
把「本手 / 恶手 / 俗手 / 新手 / 缓手 / 手割」等术语的日文/英文版列出来,
|
|
647
|
+
说明它们和插件标签的对应关系(标签本身仍用英文短词,模型友好)。
|
|
648
|
+
|
|
649
|
+
### 测试
|
|
650
|
+
|
|
651
|
+
85 项全绿
|
|
652
|
+
|
|
653
|
+
## 0.9.0 — 2026-10-28
|
|
654
|
+
|
|
655
|
+
### 热清单标题改 `LEARNED` + 每条失败边都有归属标签
|
|
656
|
+
|
|
657
|
+
**问题**:`PROVEN DEAD ENDS` 是给人类看的标题,而且里面混着三种完全不同的边:
|
|
658
|
+
- 真正的死路(没有成功路径经过)
|
|
659
|
+
- 等价成功路径(`redundant`)
|
|
660
|
+
- 探出新状态(`novel`)
|
|
661
|
+
|
|
662
|
+
**改法**:
|
|
663
|
+
|
|
664
|
+
```
|
|
665
|
+
LEARNED (2 failed attempts):
|
|
666
|
+
# dead=no working path goes through it (don't retry) | redundant=a working path reaches the same endpoint | novel=explored states no working path covered (may revisit) | longer=detours vs a working path
|
|
667
|
+
- e1 "删掉整个 node_modules" → 权限不足 [dead]
|
|
668
|
+
- e2 "绕远路到同一终点" → boom [redundant]
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
每条失败边现在**必有标签**:
|
|
672
|
+
|
|
673
|
+
| 标签 | 含义 | 该怎么做 |
|
|
674
|
+
|---|---|---|
|
|
675
|
+
| `[dead]` | 没有成功路径经过 | 别重试 |
|
|
676
|
+
| `[redundant]` | 有成功路径到同一终点 | 走那条 |
|
|
677
|
+
| `[novel]` | 探出了成功路径没走过的状态 | 可复查 |
|
|
678
|
+
| `[longer]` | 比成功路径绕远 | 走短的 |
|
|
679
|
+
|
|
680
|
+
### 测试
|
|
681
|
+
|
|
682
|
+
85 项全绿
|
|
683
|
+
|
|
684
|
+
## 0.8.0 — 2026-10-28
|
|
685
|
+
|
|
686
|
+
### `WORKING` 显示完整成功路径
|
|
687
|
+
|
|
688
|
+
之前只显示最近一条边(`user → n2`),模型不知道整条路怎么走通的。
|
|
689
|
+
现在从最新成功节点回溯到根,拼出完整路径:
|
|
690
|
+
|
|
691
|
+
```
|
|
692
|
+
WORKING: user → n2 → n3 (exit 0)
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
这是「棋谱」该有的样子:**整盘棋的行棋顺序**,不是最后一手。
|
|
696
|
+
|
|
697
|
+
### 测试
|
|
698
|
+
|
|
699
|
+
85 项全绿
|
|
700
|
+
|
|
701
|
+
## 0.7.0 — 2026-10-28
|
|
702
|
+
|
|
703
|
+
### 模型消费者视角优化(给模型用,不是给人看)
|
|
704
|
+
|
|
705
|
+
**1. 手割标记改成模型能直接理解的英文短词 + 图例**
|
|
706
|
+
|
|
707
|
+
| 旧 | 新 | 图例含义 |
|
|
708
|
+
|---|---|---|
|
|
709
|
+
| `[同型]` | `[redundant]` | same endpoint as a working path |
|
|
710
|
+
| `[探新]` | `[novel]` | explored states no working path covered |
|
|
711
|
+
| `[劣]` | `[longer]` | detours |
|
|
712
|
+
|
|
713
|
+
图例只在确实有标记时出现(省 token):
|
|
714
|
+
```
|
|
715
|
+
# tags: redundant=same endpoint as a working path | novel=explored states no working path covered | longer=detours
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
**2. 新增 `WORKING` 行 —— 模型不能只看到死路,还要知道哪条路是通的**
|
|
719
|
+
|
|
720
|
+
```
|
|
721
|
+
WORKING: user → n2 (exit 0)
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
**3. 消除 `PROVEN DEAD ENDS` 与「同型」的矛盾**:`redundant` 明确说它等价于成功路径,不是真正的死路。
|
|
725
|
+
|
|
726
|
+
### 实测热清单
|
|
727
|
+
|
|
728
|
+
```
|
|
729
|
+
<chess-ledger>
|
|
730
|
+
ROOT USER (verbatim): 目标:把构建跑通
|
|
731
|
+
CURRENT PATH: n1(user) → n2
|
|
732
|
+
CURRENT GOAL: 装好了
|
|
733
|
+
WORKING: user → n2 (exit 0)
|
|
734
|
+
PROVEN DEAD ENDS (1 total; do not retry blind):
|
|
735
|
+
# tags: redundant=same endpoint as a working path | novel=explored states no working path covered | longer=detours
|
|
736
|
+
- e1 "绕路A" → boom [redundant]
|
|
737
|
+
</chess-ledger>
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
### 测试
|
|
741
|
+
|
|
742
|
+
85 项全绿
|
|
743
|
+
|
|
744
|
+
### 待办(下一版)
|
|
745
|
+
|
|
746
|
+
- 手割多参照点:同一失败边相对多条成功路径的分别结论
|
|
747
|
+
- 真实模型 A/B:带手割标记 vs 不带,验证模型是否真的少走死路
|
|
748
|
+
|
|
749
|
+
## 0.6.0 — 2026-10-28
|
|
750
|
+
|
|
751
|
+
### 重构:手割从四档改成「两判定 + 多标签」
|
|
752
|
+
|
|
753
|
+
**问题**:四档(profit / detour / pure_loss / no_alternative)是单选,容易模棱两可:
|
|
754
|
+
- 同一条失败边可能同时「有价值」和「不如原型」;
|
|
755
|
+
- 同一个失败边可能通向多个收敛点,从不同参照看结论不同。
|
|
756
|
+
|
|
757
|
+
**改法**:判定只有**两种**,其余是**可同时成立**的标签:
|
|
758
|
+
|
|
759
|
+
| 判定 | 含义 |
|
|
760
|
+
|---|---|
|
|
761
|
+
| `same_position` | **同型** —— 失败边和某条成功路径到达同一终点(殊途同归,完全等价) |
|
|
762
|
+
| `different` | **不同型** —— 其余情况 |
|
|
763
|
+
|
|
764
|
+
不同型时额外记录两个**独立**维度:
|
|
765
|
+
|
|
766
|
+
| 字段 | 含义 | 热清单标记 |
|
|
767
|
+
|---|---|---|
|
|
768
|
+
| `probes` | 探出的、标准定式没走过的节点(最多 8 个) | `[探新]` |
|
|
769
|
+
| `vsBaseline` | 相对标准定式:`same` / `longer`(绕路)/ `unknown` | `[劣]` |
|
|
770
|
+
|
|
771
|
+
**多标签可以同时出现**:`[探新 劣]` = 这条路探出了新东西,但比标准定式绕了路。
|
|
772
|
+
|
|
773
|
+
### 实测
|
|
774
|
+
|
|
775
|
+
```
|
|
776
|
+
# 同型:失败边和成功路径到同一节点
|
|
777
|
+
- e1 "绕路A" → boom [同型]
|
|
778
|
+
|
|
779
|
+
# 探新:失败边走了标准定式没走过的节点
|
|
780
|
+
- e2 "探索路" → boom [探新]
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
### 已知局限(记在 HANDOFF)
|
|
784
|
+
|
|
785
|
+
- 多条成功路径目前取并集,**没有分别列出**「相对每条路径的结论」——不同参照点可能给出不同结论。
|
|
786
|
+
- `probes` 与 `vsBaseline: longer` 逻辑上互斥(一个要求不在基线,一个要求在基线),
|
|
787
|
+
所以 `[探新 劣]` 只在「终点在基线但沿途探新」时出现。
|
|
788
|
+
|
|
789
|
+
### 测试
|
|
790
|
+
|
|
791
|
+
85 项(4 个 tewari 测试改断言后全绿)
|
|
792
|
+
|
|
793
|
+
## 0.5.1 — 2026-10-28
|
|
794
|
+
|
|
795
|
+
### 修复:手割漏了「赚」这一档
|
|
796
|
+
|
|
797
|
+
0.5.0 只做了「亏」,但手割的核心是「谁亏谁赚」。补上 `profit` 并重排判定顺序:
|
|
798
|
+
|
|
799
|
+
| 判定 | 条件 | 标记 |
|
|
800
|
+
|---|---|---|
|
|
801
|
+
| `profit` | 同起点**没有**别的成功路径,但失败之后走出了成功 → 必要试错 | **`[赚]`** |
|
|
802
|
+
| `detour` | 标准定式(同起点成功路径)能到达失败终点,但绕了路 | `[绕路]` |
|
|
803
|
+
| `pure_loss` | 标准定式不经过它 → 这一步多余 | `[纯亏]` |
|
|
804
|
+
| `no_alternative` | 同起点没有成功路径,失败之后也没有成功 | 无 |
|
|
805
|
+
|
|
806
|
+
**判定顺序很关键**:先算「有没有标准定式」(同起点成功路径),再算「失败之后有没有成功」,
|
|
807
|
+
最后才落到 pure_loss —— 否则会把「必要试错」误判成「纯亏」。
|
|
808
|
+
|
|
809
|
+
### 实测两种输出
|
|
810
|
+
|
|
811
|
+
```
|
|
812
|
+
# 赚:没有别的成功路径,试错后走出来了
|
|
813
|
+
- e1 "先试 npm install" → ETIMEDOUT [赚]
|
|
814
|
+
|
|
815
|
+
# 纯亏:有别的成功路径,这一步多余
|
|
816
|
+
- e1 "直接改 prod" → EACCES [纯亏]
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
### 测试
|
|
820
|
+
|
|
821
|
+
**85 项**(+1:profit)
|
|
822
|
+
|
|
823
|
+
## 0.5.0 — 2026-10-28
|
|
824
|
+
|
|
825
|
+
### 新增:手割分析(tewari)
|
|
826
|
+
|
|
827
|
+
围棋的复盘方法:把多出的着法拿掉,还原标准定式,判断谁亏谁赚。
|
|
828
|
+
本插件用它判断**一条失败边是不是纯亏**:
|
|
829
|
+
|
|
830
|
+
| 判定 | 含义 | 热清单标记 |
|
|
831
|
+
|---|---|---|
|
|
832
|
+
| `pure_loss` | 同起点有成功路径,且完全不经过失败边的终点 | **`[纯亏]`** |
|
|
833
|
+
| `detour` | 成功路径能到达失败终点,但绕了路 | `[绕路]` |
|
|
834
|
+
| `no_alternative` | 同起点没有成功路径可比 | 无标记 |
|
|
835
|
+
|
|
836
|
+
**为什么重要**:原来的插件只记录「e1 失败了」,手割进一步回答「**为什么**这一步多余」——
|
|
837
|
+
把这一步拿掉,同起点有成功的替代路径。这正是围棋复盘里「手割」做的事。
|
|
838
|
+
|
|
839
|
+
**实测输出**:
|
|
840
|
+
|
|
841
|
+
```
|
|
842
|
+
PROVEN DEAD ENDS (1 total; do not retry blind):
|
|
843
|
+
- e1 "直接改 prod 配置" → EACCES: permission denied [纯亏]
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**实现**:
|
|
847
|
+
|
|
848
|
+
- `graph.mjs` 新增 `tewariAnalysis(g, edge)`:对失败边做 BFS,找同起点的成功路径,判断终点是否可达
|
|
849
|
+
- `ledger.mjs` 的 `renderFailureLine` 支持 tewari 参数,热清单显示 `[纯亏]` / `[绕路]`
|
|
850
|
+
- 只对**当前显示**的失败边做,且 ≤30 条(每条一次 BFS,防 O(E²))
|
|
851
|
+
- 失败边没有终点节点时,同起点有成功替代即判 `pure_loss`
|
|
852
|
+
|
|
853
|
+
### 测试
|
|
854
|
+
|
|
855
|
+
**84 项**(+3:pure_loss / detour / no_alternative)
|
|
856
|
+
|
|
857
|
+
## 0.4.0 — 2026-10-28
|
|
858
|
+
|
|
859
|
+
### 破坏性变更:包名 `dsh-kifu-context` → `dsh-gokifu-compact`
|
|
860
|
+
|
|
861
|
+
命名拆开看:**GO(围棋)+ kifu(棋谱)+ compact(压缩)**。
|
|
862
|
+
|
|
863
|
+
- **Go**:棋种
|
|
864
|
+
- **kifu**:棋谱(围棋/将棋的记谱方式:一局棋的完整记录 + 每手评语)
|
|
865
|
+
- **compact**:这个插件实际做的事(上下文压缩)
|
|
866
|
+
|
|
867
|
+
比 `kifu-context` 更明确:`context` 只说明「上下文」没说明「压缩」;`GOkifu` 把棋种和棋谱都标出来。
|
|
868
|
+
|
|
869
|
+
**展示名用大写 GO**(`GO` 才是围棋);npm 包名只能小写(`dsh-gokifu-compact`,npm 硬限制)。
|
|
870
|
+
|
|
871
|
+
### 术语澄清:`transposition` 不是核心
|
|
872
|
+
|
|
873
|
+
- `transposition`(转置检测)是**国际象棋引擎**的概念(同一局面经不同路径到达时不重复搜索)。
|
|
874
|
+
- 围棋有等价情形(棋界叫「同形」/「同型」),但没有这个术语。
|
|
875
|
+
- 本插件里它只是**优化**:命中历史节点时不新建分支,加一条回边。
|
|
876
|
+
- **核心是「失败记忆 + 增量 fold」**:
|
|
877
|
+
- 失败记忆负责**明确否定走错的着法**(`failureEdges` + 热清单 + 节点 `errorSnippet`)
|
|
878
|
+
- 增量 fold 负责**每段历史只摘要一次**(不重压、不 ρ^k 衰减)
|
|
879
|
+
|
|
880
|
+
README 已按这个口径改写:卖点从「转置检测」改为「失败记忆 + 评语可复盘」。
|
|
881
|
+
|
|
882
|
+
### 升级步骤
|
|
883
|
+
|
|
884
|
+
```bash
|
|
885
|
+
node test/rollback.mjs # 卸旧名
|
|
886
|
+
node test/install.mjs # 装新名
|
|
887
|
+
# 重启 DSH
|
|
888
|
+
```
|
|
889
|
+
|
|
890
|
+
## 0.3.0 — 2026-10-28
|
|
891
|
+
|
|
892
|
+
### 破坏性变更:包名 `dsh-chess-context` → `dsh-gokifu-compact`
|
|
893
|
+
|
|
894
|
+
`chess` 在英文里是国际象棋,而这个插件的隐喻是**围棋棋谱(kifu)**。改名原因见下。
|
|
895
|
+
|
|
896
|
+
**升级步骤**(已装过的):
|
|
897
|
+
|
|
898
|
+
```bash
|
|
899
|
+
node test/rollback.mjs # 先卸旧名
|
|
900
|
+
node test/install.mjs # 装新名
|
|
901
|
+
# 重启 DSH
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
preset 的 `cordis.patch.yml` 与 profile 的 `package.json` 里的引用已同步更新。
|
|
905
|
+
|
|
906
|
+
### 新隐喻(写进 README 与仓库描述)
|
|
907
|
+
|
|
908
|
+
> 把 agent 的每一步变成棋谱上的一手:落子、评语、复盘。
|
|
909
|
+
> 上下文压缩不再是丢掉历史,而是把历史下成一局随时能复盘的棋 ——
|
|
910
|
+
> 每一手都保留 LLM 自己写下的评语和完整想法,环环相扣。
|
|
911
|
+
> 高价值的棋局几年后仍能记起整盘怎么下;走到关键处,旧棋谱会吊起记忆,让人悬崖勒马。
|
|
912
|
+
|
|
913
|
+
- **节点 = 一手棋**(局面)
|
|
914
|
+
- **边 = 一手尝试**(落子 + 结果)
|
|
915
|
+
- **评语 = LLM 当时写下的目标 / 约束 / 失败原因**(可追溯到完整想法)
|
|
916
|
+
- **复盘 = 从根节点沿边走一遍,整盘怎么下的都在**
|
|
917
|
+
|
|
918
|
+
### 保留项
|
|
919
|
+
|
|
920
|
+
- `transposition`(转置检测)术语保留 —— 那是国际象棋引擎的概念
|
|
921
|
+
(同一局面经不同路径到达时不重复搜索),本插件确实借用了。
|
|
922
|
+
|
|
923
|
+
## 0.2.1 — 2026-10-28
|
|
924
|
+
|
|
925
|
+
### 文档
|
|
926
|
+
|
|
927
|
+
- **修正隐喻**:`package.json` / GitHub 仓库描述里的 `chess-record DAG`(国际象棋)改为
|
|
928
|
+
**go game record (kifu)**(围棋棋谱)。项目名保留 `chess`(已发布,改名成本高于收益),
|
|
929
|
+
但隐喻取围棋:**节点 = 局面(交叉点),边 = 一手尝试(落子 + 结果),失败记忆 = AlphaGo 的胜负回溯**。
|
|
930
|
+
- 代码里的 `transposition`(转置检测)**保留不改** —— 那是国际象棋引擎的术语
|
|
931
|
+
(同一局面经不同路径到达时不重复搜索),本插件确实借用了这个概念。
|
|
932
|
+
所以准确表述是「围棋棋谱 + 国际象棋转置表」的混合,README 顶部已写明。
|
|
933
|
+
|
|
934
|
+
## 0.2.0 — 2026-10-28
|
|
935
|
+
|
|
936
|
+
> 从 0.1.0 到 0.2.0 累计修掉 **19 个 bug**(3 个 P0 级数据破坏),
|
|
937
|
+
> 单测从 64 项增到 81 项,全部通过。核心行为变化:约束不再经过模型。
|
|
938
|
+
|
|
939
|
+
### 新增
|
|
940
|
+
|
|
941
|
+
- **机械约束段**:`summarize()` 在模型输出后机械追加 `## 约束(机械保留,逐字;不由模型改写)`。
|
|
942
|
+
多规模实测(5/15/30 条失败边)发现模型会把 3 条约束全丢(0/2~3/3 之间跳),
|
|
943
|
+
改为规则拼回后约束保留率 **100%**,不依赖模型遵守。
|
|
944
|
+
- **L5 降级档**:`hotLedgerMaxTokens` 在小预算下多一档兜底(只留最近 10 条),极端输入不再超预算。
|
|
945
|
+
- **`compactRegion` 覆盖**:官方 `/compact` 路径也能拿到正确的 fold 范围(摘要里的 seq 不再是 `undefined-undefined`)。
|
|
946
|
+
- **`renderLedger` 置换提示**:当前路径上有 `transposition` 边时输出「回到已走过的状态」警告
|
|
947
|
+
—— 之前 `renderTranspositionWarning` 全项目无调用点,这个提示永远不会出现。
|
|
948
|
+
- **`validate()` 落盘前校验**:图不变量(悬空边 / 缺状态哈希 / 失败边没原因)有问题时进日志。
|
|
949
|
+
|
|
950
|
+
### 修复(19 个)
|
|
951
|
+
|
|
952
|
+
**P0(会悄悄破坏图数据)**
|
|
953
|
+
|
|
954
|
+
- `this.flushTimers` 从未初始化 → 每次「有变化」的事件抛 TypeError,**1.2s debounce 落盘从未工作**。
|
|
955
|
+
- 节点创建写死 `worldHash: "pending"`,fold 前统一回填成**同一个哈希** → 整段路径被判定为同一状态、
|
|
956
|
+
折叠成一个节点(实测 4 个 step 后节点 5→2、3 条边 `from` 悬空)。
|
|
957
|
+
- `mergeNodeInto` 只改 `edge.to` 不改 `edge.from` → 合并非叶子节点后它的所有出边指向已删除节点
|
|
958
|
+
(真实会话 155 条边里 **115 条** `from` 悬空)。
|
|
959
|
+
|
|
960
|
+
**P1**
|
|
961
|
+
|
|
962
|
+
- 热清单每次 digest 变化就**追加**新 user 消息、旧的不替换(真实会话累积 131 条 / 508,308 字符)。
|
|
963
|
+
**已缓解**:两次注入至少隔 40 事件 + 失败边增长不足 5 条不注入。
|
|
964
|
+
- `renderMd` 对每个节点做一次全边扫描 O(N×E) → 建 `from→edges[]` 索引后 **406ms → 1.3ms(258 倍)**。
|
|
965
|
+
- 热清单只看 root 节点的约束,后续 user 消息里的约束全部丢失 → 改用 `collectConstraints(g)` 全量去重。
|
|
966
|
+
- 测试计数正则对只读工具也生效(`read` 到 "all tests passed" 被判 success)→ 加 `if (!readOnly)`。
|
|
967
|
+
- `EXIT_RE` 取正文第一处匹配(`sed` 打印的测试文件里写着 `[exit code: 1]` 会把 exit 0 的命令判失败)
|
|
968
|
+
→ 只看末尾 200 字符。
|
|
969
|
+
- `renderFacts` 无范围限制,摘要体积随**全局**失败数增长 → 支持 `{ range }` 只取本段失败边。
|
|
970
|
+
- `backfillState` 在 `compactRegion` 之前执行,fold 失败不回滚 → fold 前 `toJSON` 快照,
|
|
971
|
+
`range===null` / `result===null` / 抛错三条路径都恢复。
|
|
972
|
+
- `validate()` 运行期从不调用 → `#flush` 落盘前校验。
|
|
973
|
+
- 置换命中信息被 keeper 丢弃,`renderTranspositionWarning` 无调用点 → 在 `renderLedger` 里真正输出。
|
|
974
|
+
- 指令同时要求「每条失败边都必须出现」和「整份记录 <1200 字符」→ 超过约 15 条死路不可满足。
|
|
975
|
+
改为「每条死路约 40 字符 + 600 字符余量」。
|
|
976
|
+
|
|
977
|
+
**P2**
|
|
978
|
+
|
|
979
|
+
- L4 降级不看 `maxTokens`(12 条 200 字约束 + 120 条失败边 → 1,095 tokens,预算 500 的 219%)→ 加 L5。
|
|
980
|
+
- `_chessActiveRange` 在 `/compact` 路径为 null → 覆盖 `compactRegion` 在事务入口设置、`finally` 恢复。
|
|
981
|
+
- `summaryMode: "llm"` 的文档说「完全交给模型」,实际仍带 facts → 文档改为「不降级到规则摘要,仍带硬事实」。
|
|
982
|
+
|
|
983
|
+
**运行期实测(真实会话暴露)**
|
|
984
|
+
|
|
985
|
+
- `user/message` 的 `source.kind` 只应把 `user` 当真用户
|
|
986
|
+
(hindsight / agent-instructions / subagent 注入被当成 UserNode,污染约束集与根目标)。
|
|
987
|
+
真实日志回放:user 节点 **22 → 4**。
|
|
988
|
+
- verifier 把只读工具(`get_goal`/`update_goal`/`hindsight_*`)的 JSON 文本误判为 failure。
|
|
989
|
+
真实日志回放:failure **88 → 22**。
|
|
990
|
+
- `tool/result` 与 `pendingEdges` 的匹配缺失 → 回放 1807 事件,未匹配 **0 条**。
|
|
991
|
+
- `EXIT_RE` 渲染(同上)。
|
|
992
|
+
|
|
993
|
+
### 变更
|
|
994
|
+
|
|
995
|
+
- `src/engine.mjs` 去掉内嵌**裸 NUL 字节**(`parts.join("\0")` → `String.fromCharCode(0)`),
|
|
996
|
+
`file`/`grep` 不再把整个文件判为 binary。
|
|
997
|
+
- `package.json` 的 `files` 排除测试产物(`src/.engine-under-test.mjs` / `src/.harness-stubs`)。
|
|
998
|
+
|
|
999
|
+
### 文档
|
|
1000
|
+
|
|
1001
|
+
- 新增 [`QUICKSTART.md`](./QUICKSTART.md):重启后 3 步验证 + 日常使用 + 4 类故障处理 + 7 个配置项。
|
|
1002
|
+
- 新增 [`docs/性能与成本.md`](./docs/性能与成本.md):fold 耗时分解 / graph 体积 / ledger 渲染 / 真实 token 曲线。
|
|
1003
|
+
- 新增 [`evidence/棋谱有效性实验.md`](./evidence/棋谱有效性实验.md):干净子代理实验
|
|
1004
|
+
—— 棋谱组 **15/15** 避开已知坑;对照组从原始文档补出 **2 条棋谱漏掉的坑**,
|
|
1005
|
+
证明「原始记忆必须保留」。
|
|
1006
|
+
- 全部文档数字按 `evidence/*.json` 校正(验收子代理查出 15 处不一致,已修 14 处,剩 1 处标注口径)。
|
|
1007
|
+
|
|
1008
|
+
### 测试
|
|
1009
|
+
|
|
1010
|
+
| 套件 | 结果 |
|
|
1011
|
+
|---|---|
|
|
1012
|
+
| `node test/run.mjs` | **81 passed, 0 failed**(0.1.0 时 64 项) |
|
|
1013
|
+
| `node test/verify-install.mjs` | 13/13 |
|
|
1014
|
+
| `node test/real-modules.mjs` | 4/4(真实 `@deepseek-ai/*` 包) |
|
|
1015
|
+
| `node test/real-fold.mjs` | 5/5(真实 `compactRegion` 事务,含 hybrid) |
|
|
1016
|
+
| `node test/real-e2e.mjs` | 3/3 失败边、3/3 复述 |
|
|
1017
|
+
| 真实模型对照 | 本插件失败边 **8/8** vs 官方 8 段模板 **4.67/8** |
|
|
1018
|
+
|
|
1019
|
+
### 已知未完成(见 HANDOFF.md)
|
|
1020
|
+
|
|
1021
|
+
- P1-4 的彻底修法(替换 surface 上的旧热清单消息)—— 当前是限流缓解。
|
|
1022
|
+
- 真实计费口径的节省(模拟显示 22.7%–43.3%,未核对真实账单)。
|
|
1023
|
+
- 三层文件树(index / nodes / raw)的设计已验证,尚未进插件实现。
|