@a9i5k4/dsh-auto-memory 3.1.5 → 3.1.7
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/docs/CONTINUITY-FLOW.md +6 -6
- package/docs/HANDBOOK.md +54 -53
- package/docs/M-CM-PLAN.md +1 -1
- package/docs/M-CM-STATE.md +1 -1
- package/docs/M-CM7-HANDOFF-LAYERED-RETRIEVAL.md +1 -1
- package/docs/M3B-CONTRACT.md +7 -7
- package/docs/M7-AUTONOMOUS-STATE.md +1 -1
- package/docs/M7-TASKSET-DISPATCH.md +1 -1
- package/docs/PROMPT-PACK-LAYERED-RECALL.md +3 -3
- package/docs/PROMPT-SET-STRICT.md +3 -3
- package/docs/RELEASE-GO-NOGO.md +1 -1
- package/docs/STATUS-BOARD.md +1 -1
- package/docs/USER-GUIDE.en.md +21 -21
- package/docs/USER-GUIDE.zh-CN.md +21 -21
- package/docs/WHITEPAPER.md +1 -1
- package/docs/prompts/FIX-AGENT-P12-FULL-REGRESSION.md +1 -1
- package/docs/prompts/LIVE-VERIFY-ZCODE.md +2 -2
- package/docs/prompts/P2-semantic-recall.md +2 -2
- package/docs/prompts/P7-write-fix.md +1 -1
- package/docs/prompts/RELEASE-AGENT.md +4 -4
- package/docs/prompts/ZCODE-DROPIN.md +1 -1
- package/lib/acceptance.js +6 -6
- package/lib/activation-host.js +15 -14
- package/lib/activation-inbox-state.js +4 -4
- package/lib/activation-inbox.js +44 -44
- package/lib/board-mode.js +3 -3
- package/lib/client.js +225 -41
- package/lib/config-io.js +12 -12
- package/lib/context-bridge.js +22 -22
- package/lib/context-host.js +24 -23
- package/lib/datadir.js +95 -0
- package/lib/degrade.js +21 -21
- package/lib/dsh-home.js +8 -8
- package/lib/engine-identity.js +12 -12
- package/lib/engine-switch.js +3 -3
- package/lib/episodic-store.js +13 -13
- package/lib/evidence-agg.js +4 -4
- package/lib/evidence-store.js +12 -12
- package/lib/fact-store.js +47 -47
- package/lib/handoff-anchor.js +4 -4
- package/lib/hub-io.js +356 -3
- package/lib/index-sync.js +5 -5
- package/lib/index.js +426 -242
- package/lib/intent-clean-safe.js +3 -3
- package/lib/intent-clean.js +1 -1
- package/lib/l0-extract.js +15 -15
- package/lib/l0-index-sync.js +8 -8
- package/lib/l0-index.js +11 -11
- package/lib/ledger-criteria.js +8 -8
- package/lib/m4-corpus.js +1 -1
- package/lib/m7-index-sync-host.js +2 -2
- package/lib/m7-wire.js +24 -24
- package/lib/memory-anchor.js +1 -1
- package/lib/memory-envelope.js +15 -15
- package/lib/memory-hub.js +95 -50
- package/lib/memory-importance.js +7 -7
- package/lib/memory-mutation.js +5 -5
- package/lib/note-status-apply.js +2 -2
- package/lib/note-status.js +7 -7
- package/lib/policies/activation_policy_v2.json +2 -2
- package/lib/policies/recall_intent_lr_v1.json +1 -1
- package/lib/procedure-observation.js +2 -2
- package/lib/procedure-store.js +117 -28
- package/lib/python-setup.js +6 -5
- package/lib/python-sidecar-client.js +26 -26
- package/lib/recall-fusion.js +12 -12
- package/lib/recall-stats.js +36 -1
- package/lib/rerank-host.js +11 -11
- package/lib/rules-edit.js +9 -9
- package/lib/rules-layer.js +26 -26
- package/lib/semantic-decide.js +7 -7
- package/lib/semantic-js.js +13 -13
- package/lib/shadow-host.js +7 -6
- package/lib/shadow-retrieval.js +40 -40
- package/lib/skill-export-host.js +7 -7
- package/lib/skill-export.js +6 -6
- package/lib/state-commit.js +10 -10
- package/lib/storage-manage.js +6 -6
- package/lib/tier-layer-inject.js +28 -28
- package/lib/tier0-catalog.js +4 -4
- package/lib/wb-contract.js +45 -45
- package/lib/wb-sidecar.js +11 -11
- package/package.json +3 -4
- package/python/m7_activation_features_v2.py +7 -7
- package/python/m7_embedding_v1.py +12 -12
- package/python/policies/activation_policy_v2.json +2 -2
- package/python/policies/decision-record-activation-v2-delta-exp-override-20260824.json +1 -1
- package/python/policies/decision-record-reasoning-kind-admission-20260826.json +2 -2
- package/python/policies/decision-record-stale-gate-per-candidate-20260825.json +2 -2
- package/python/policies/recall_intent_lr_v1.json +1 -1
- package/python/verify_policy_artifact.py +3 -3
- package/python/worker_semantic_v1.py +18 -18
- package/python/worker_v1.py +18 -18
package/docs/USER-GUIDE.zh-CN.md
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
- 面板标题里的版本号与 设置 →「检查更新」显示的都是**当前安装的版本**。
|
|
51
51
|
- 侧栏还有一颗**悬浮钉**(线描快捷入口),可从任何页面快速唤出记忆操作。
|
|
52
52
|
- DSH 0.1.2-rc.1 起 Web UI 有 token 认证闸门(每次重启换新 token,启动日志里 `?token=…` 即访问地址);本插件的 HTTP 端点仅本机回环可访问,不受闸门影响。
|
|
53
|
-
- 数据全在本机:`~/.dsh/memory/`(记忆文件)、`~/.dsh/dsh-auto-memory.json
|
|
53
|
+
- 数据全在本机:`~/.dsh/memory/`(记忆文件)、`~/.dsh/dsh-auto-memory.json`(配置)。**注意**:去 pre 后源码名即发布名,仓库与 npm 安装的路径**完全一致**,下面所有路径两边通用。
|
|
54
54
|
|
|
55
55
|
## 2. 第一次启动
|
|
56
56
|
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
| 唤起冷却(分钟)(jsDecideCooldownRounds) | 1 | 注入后 N 轮内不再判定,防连续唤起浪费 token;**0=不冷却**(合法值) |
|
|
99
99
|
| 唤起 margin 阈值(jsDecideDeltaExp) | 0.01 | 候选第 1/2 名分差须超过此值才注入(e5 余弦分布紧,默认 0.01;bge-m3 校准值 0.03)。调小=更容易唤起,调大=更保守;0=不过滤 |
|
|
100
100
|
| 唤起候选方案(jsDecideCandidateScheme) | `balanced` | balanced=3 条×40 字符(信息量/token 平衡);dense=6 条×20 字符(更多候选更广联想);custom=自定义条数(1-8)与长度 |
|
|
101
|
-
| 唤起注入内容长度(jsDecideExcerptChars) | 40 | Reference 行内容上限。40=关键词级(省 token,细节由模型 `
|
|
101
|
+
| 唤起注入内容长度(jsDecideExcerptChars) | 40 | Reference 行内容上限。40=关键词级(省 token,细节由模型 `memory_read` 取全文);可调 20-480 |
|
|
102
102
|
| 检索模式(semanticEngineMode) | `auto` | **auto**=内置语义就绪即用,否则词法保底;**lexical**=仅词法;**js**=内置语义(e5-small,约 130MB);**python**=高级 Python(BGE-M3 int8,约 563MB)。详见 §5。旁边的 **⟳ 检测** 按钮一键体检环境,缺资产时自动弹安装引导卡 |
|
|
103
103
|
| 思维链监听(reasoningObserverEnabled) | 开 | 把模型思维链纳入实时观测 `(重启生效)`——闭源模型的概括式思维链同样纳入,是「边做边想起」的重要信号源 |
|
|
104
104
|
| 分支会话观测(contextBridgeObserveChildSessions) | 开 | 跨天续接的会话标记为分支后同样纳入观测 |
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
| 项 | 默认 | 怎么调 |
|
|
179
179
|
|---|---|---|
|
|
180
180
|
| 交接白板(handoffEnabled) | 关 | **PLAN.md 全貌快照 + 四段式交接账本**:模型在理解全貌/阶段完成时写入,注入动态快照首位,白板页签实时可看,跨窗口续命。建议开启 |
|
|
181
|
-
| 白板注入预算(handoffPlanChars) | 1200 | PLAN.md 注入动态快照的硬截断预算;全文经 `
|
|
181
|
+
| 白板注入预算(handoffPlanChars) | 1200 | PLAN.md 注入动态快照的硬截断预算;全文经 `memory_read` 或白板页查看 |
|
|
182
182
|
| 账本注入预算(handoffLedgerChars) | 800 | 最新账本的注入预算;账本内部按四段权重截断(失败原因 .35 > 下一步 .30 > 目标 .20 > 状态 .15,从最低权重段起截) |
|
|
183
183
|
| 水位估计窗口(token)(waterLevelWindowTokens) | 0=自动 | 0 表示自动:优先官方路由容量,其次按当前会话模型查 settings.yaml。**除非特殊模型,保持 0** |
|
|
184
184
|
| 水位建议阈值(waterLevelThreshold) | 0.75 | 越阈即注入交接建议并自动补写账本。**默认 0.75 而非 0.8**:官方自动压缩阈值是 80%,贴着 80% 常被官方抢先压缩,留 5% 余量(1M 窗口约 50K token)才来得及走完交接 |
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
|
|
202
202
|
## 5. 检索专题
|
|
203
203
|
|
|
204
|
-
一次 `
|
|
204
|
+
一次 `memory_recall`(或面板检索页)背后,召回走的是**多臂融合**管线:
|
|
205
205
|
|
|
206
206
|
### 5.1 四个检索臂
|
|
207
207
|
|
|
@@ -217,7 +217,7 @@
|
|
|
217
217
|
- 各臂排名经 **RRF(rank-space 倒数排名融合,k=60)** 合并——只看名次不看绝对分,任何一臂缺席都不扰动其余结果。
|
|
218
218
|
- 查询词先经 **QueryPlan 组装**(窗口 8 段/4096 字符预算、最多 32 个词项);词项按**权重降序**保留(用户/触发词 1.0 > 近期用户消息 0.8 > 工具结果 0.6 > 思维链 0.5 > 工具调用 0.4 > 助手输出 0.2),超预算时截掉的是低权重词,高权重的关键问句词永不被丢。
|
|
219
219
|
- 默认返回 **L0 摘要列表**:每条约 93 字符(压缩 6.78:1),含 `id`、得分、匹配原因(`词法×N` / `语义×x.xx`)——一次检索只花十分之一的 token。
|
|
220
|
-
- 要看某条原文:把它的 id 传给 `expand="mem_xxx"`(或 `
|
|
220
|
+
- 要看某条原文:把它的 id 传给 `expand="mem_xxx"`(或 `memory_read`),按锚点**字节区间**直接定位原文,精确不串条。
|
|
221
221
|
- 检索范围 `scope`:`all`(默认,含白板语料+跨工作区+外部记忆+历史会话)/ `handoff`(只搜交接白板——接续长任务先查这里)/ `sessions`(只搜历史会话)。
|
|
222
222
|
- 查不存在的主题:正常返回空或弱命中,不报错不阻塞(fail-soft)。
|
|
223
223
|
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
|
|
251
251
|
## 7. 证据链与记忆重要性
|
|
252
252
|
|
|
253
|
-
每条记忆都有可审计的使用档案,六类事件按日落盘 `~/.dsh/memory/evidence/events/YYYY-MM-DD.jsonl
|
|
253
|
+
每条记忆都有可审计的使用档案,六类事件按日落盘 `~/.dsh/memory/evidence/events/YYYY-MM-DD.jsonl`:
|
|
254
254
|
|
|
255
255
|
| 事件 | 含义 |
|
|
256
256
|
|---|---|
|
|
@@ -334,17 +334,17 @@ AI 在对话中可直接调用(共 14 个,你不需要记):
|
|
|
334
334
|
|
|
335
335
|
| 工具 | 作用 |
|
|
336
336
|
|---|---|
|
|
337
|
-
| `
|
|
338
|
-
| `
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
| `
|
|
342
|
-
| `
|
|
343
|
-
| `
|
|
344
|
-
| `
|
|
345
|
-
| `
|
|
346
|
-
| `
|
|
347
|
-
| `
|
|
337
|
+
| `memory_recall` | 检索记忆:本地记忆(全工作区日志/笔记/反思/白板)+ 跨工作区 + 外部记忆 + 历史会话。默认返回 L0 摘要列表;`expand` 展开原文;`scope=handoff/sessions` 直达 |
|
|
338
|
+
| `memory_read` | 按需读取某条记忆/某天日志/反思/笔记全文 |
|
|
339
|
+
| `memory_note` | 写项目笔记 / 交接账本 / 重写白板 PLAN(`kind=plan/handoff`) |
|
|
340
|
+
| `memory_log` | 追加今日日志(append-only) |
|
|
341
|
+
| `memory_user` | 跨项目长期规则读写 |
|
|
342
|
+
| `memory_reflect` | 保存每日反思 |
|
|
343
|
+
| `memory_consolidate` | 做梦式固化:读最近日志发散提炼长期要点 |
|
|
344
|
+
| `memory_maintain` | 30 天蒸馏:旧日志提炼进笔记,原文归档,一字不丢 |
|
|
345
|
+
| `memory_status` | 记忆系统状态总览 |
|
|
346
|
+
| `memory_external` | 外部记忆源管理(扫描/接入/移除其他 AI 工具的记忆) |
|
|
347
|
+
| `calendar_add` / `calendar_list` / `calendar_done` / `calendar_remove` | 日程管理——AI 主动从对话提取截止日期,未完成事项持续提醒 |
|
|
348
348
|
|
|
349
349
|
三个写入工具(log/note/user)全部过**写入口闸门**:GBK 乱码、口吃退化、连续重复行、外部 AI 人设 JSON、base64 残留一律拒收并给人类可读原因;单次追加 ≤8000 字符、重写 ≤200000 字符、追加与最近约 60 行去重。**凭据/密钥段永远不进提示词。**
|
|
350
350
|
|
|
@@ -374,13 +374,13 @@ AI 在对话中可直接调用(共 14 个,你不需要记):
|
|
|
374
374
|
|
|
375
375
|
| 内容 | 路径 |
|
|
376
376
|
|---|---|
|
|
377
|
-
| 插件配置 | `~/.dsh/dsh-auto-memory.json`(本仓库 pre 开发树为 `dsh-auto-memory
|
|
377
|
+
| 插件配置 | `~/.dsh/dsh-auto-memory.json`(本仓库 pre 开发树为 `dsh-auto-memory.json`) |
|
|
378
378
|
| 用户级记忆 | `~/.dsh/memory/MEMORY.md` |
|
|
379
379
|
| 工作区记忆 | `~/.dsh/memory/workspaces/<工作区>/`(MEMORY.md、每日日志、handoff/、reflections/、summaries/) |
|
|
380
380
|
| 白板与账本 | `~/.dsh/memory/workspaces/<工作区>/handoff/`(PLAN.md + handoff-*.md) |
|
|
381
|
-
| 记忆中枢三层 | `~/.dsh/memory/hub/`(episodes / facts / procedures .json
|
|
382
|
-
| 证据事件 | `~/.dsh/memory/evidence/events/YYYY-MM-DD.jsonl
|
|
383
|
-
| 语义引擎数据 | `~/.dsh/memory/semantic/`(发射配置 embedding-config.json
|
|
381
|
+
| 记忆中枢三层 | `~/.dsh/memory/hub/`(episodes / facts / procedures .json,原子写) |
|
|
382
|
+
| 证据事件 | `~/.dsh/memory/evidence/events/YYYY-MM-DD.jsonl`(六类,按日) |
|
|
383
|
+
| 语义引擎数据 | `~/.dsh/memory/semantic/`(发射配置 embedding-config.json、决策影子日志、向量缓存) |
|
|
384
384
|
| 语义模型/venv | `~/.dsh/models/js-semantic/`(C2 模型)· `~/.dsh/python-engine/`(C3 venv+模型,升级插件不受影响) |
|
|
385
385
|
| 子代理痕迹备份 | `~/.dsh/subagent-gc-backup/`(移回 `~/.dsh/sessions/` 即回滚) |
|
|
386
386
|
| 诊断日志 | `~/.dsh/dsh-auto-memory-diagnose.log`(与 `memory/` 同级,不在 `memory/` 里面) |
|
package/docs/WHITEPAPER.md
CHANGED
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
|
|
88
88
|
| 项 | 数量 | 说明 |
|
|
89
89
|
|---|---|---|
|
|
90
|
-
| 模型工具 | **17** | 15 个基础 + 2 个条件注册(`
|
|
90
|
+
| 模型工具 | **17** | 15 个基础 + 2 个条件注册(`memory_expand` / `memory_trace` 仅在 `boardMode=graph` 时注册) |
|
|
91
91
|
| HTTP 路由 | **49** | 全部 loopback-only;插件层外部访问返回 403,宿主层为 401——**两者都是预期行为** |
|
|
92
92
|
| 设置键 | **98** | 其中 **60** 个可在设置页写入 |
|
|
93
93
|
| 面板页签 | **12** | 概览 / 日志 / 唤起回顾 / 记忆中枢 / 存储管理 / 笔记 / 白板 / 反思 / 接续 / 日历 / 检索 / 工作区 |
|
|
@@ -88,7 +88,7 @@ node tests/smoke/smoke-test-continue-chain-pre.mjs # 58
|
|
|
88
88
|
| # | 功能 | 怎么验 | 通过标准 |
|
|
89
89
|
|---|---|---|---|
|
|
90
90
|
| **L1** | **主动联想(P12 直接影响面)** | 开一个新会话,聊一段与已有记忆主题相关的话 | 记忆被**主动**联想并注入;从日志/diag 看 `queryPlan` 保留的词里**含高权重来源(user/trigger)的词** |
|
|
91
|
-
| **L2** | **语义检索(P8)** | 用 `
|
|
91
|
+
| **L2** | **语义检索(P8)** | 用 `memory_recall` 查一个**词法不重合但语义相关**的查询(如记忆里写"npm 发布报 ENEEDAUTH",查"发布凭证问题") | 能召回。失败则切 `legacy` 对比——若 legacy 正常而 rrf 失败 ⇒ **P8 回归** |
|
|
92
92
|
| **L3** | L0 返回与展开 | 同 L2 的 recall | 返回 L0 列表(含 id/score),用 `expand="mem_xxx"` 能取到原文 |
|
|
93
93
|
| **L4** | M8 记忆中枢 | 浏览器打开记忆面板 | 三栏(技能/事实/经历)有内容或正确空态;`GET /api/dsh-auto-memory-pre/memory-hub` 返回 200 + overview |
|
|
94
94
|
| **L5** | 证据落盘 | 查看 `C:\Users\JH Z\.dsh\memory\evidence-pre\events\` 当日文件 | 有 `seen` 事件新增 |
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
| # | 功能 | 怎么验(用你的电脑控制操作 UI) | 通过标准 | 你要贴的证据 |
|
|
39
39
|
|---|---|---|---|---|
|
|
40
40
|
| **L1** | **主动联想** | 新开一个会话,聊一段与已有记忆主题相关的话 | 记忆被**主动**联想并注入(无需用户查询) | 注入内容的截图 + 后台日志里对应记录 |
|
|
41
|
-
| **L2** | **语义检索** | 调用 `
|
|
41
|
+
| **L2** | **语义检索** | 调用 `memory_recall`,查一个**词法不重合但语义相关**的查询(记忆里写"npm 发布报 ENEEDAUTH",查"发布凭证问题") | 能召回 | 返回结果截图/文本。**若失败,切 `legacy` 再测一次对比** |
|
|
42
42
|
| **L3** | L0 返回与展开 | 同 L2 | 返回 L0 列表(含 id/score/match_reason);用 `expand="mem_xxx"` 能取到原文 | 两次调用的返回文本 |
|
|
43
|
-
| **T1** | **时间臂(本版新功能)** | 用 `
|
|
43
|
+
| **T1** | **时间臂(本版新功能)** | 用 `memory_recall` 查**含时间表达**的查询,如"上周的记忆";再查一条**不含时间词**的同类查询做对照 | 含时间表达时,对应时间范围的日志条目排序**上升**;不含时间词时排序**与对照一致**(零变更) | 两次 top-5 的 `id` 序列对比 |
|
|
44
44
|
| **L4** | M8 记忆中枢 | 打开记忆面板 | 三栏(技能/事实/经历)有内容或正确空态 | 面板截图 + `GET /api/dsh-auto-memory-pre/memory-hub` 的响应(应 200 + overview) |
|
|
45
45
|
| **L5** | 证据落盘 | 对话若干轮后看当日 events 文件 | 有 `seen` 事件新增;**若能触发一次用户纠正**(对话里说"不对,你记错了"之类),应有 `correction` | events 文件新增行的 JSON(脱敏) |
|
|
46
46
|
| **L6** | 跨窗口接续 | 让水位涨到 75% 触发自动接续(或手动一键接续) | 新会话收到**分层**材料(白板/账本/近期线程),且**不再要求先 read 转写** | 新会话首条注入内容截图 |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**目标**:`memory_recall` 当前为纯词法(工具描述自述"关键词匹配")。接入语义臂,**输入用 L0 而非全文**(全文会超 e5 512 token 上限被截断)。
|
|
6
6
|
|
|
7
|
-
**涉及功能模块**:`lib/index.js` 的 `recall()` 实现与 `
|
|
7
|
+
**涉及功能模块**:`lib/index.js` 的 `recall()` 实现与 `memory_recall` 工具定义;`lib/semantic-js-pre.js`(C2);`lib/shadow-retrieval-pre.js`(词法臂)。
|
|
8
8
|
|
|
9
9
|
**验收标准**:
|
|
10
10
|
1. 主题性查询("发布踩坑")能召回词法不重合但语义相关的记忆
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
**需先检索的仓库路径与符号关键词**:
|
|
17
17
|
- 路径:`lib/index.js`、`lib/semantic-js-pre.js`、`lib/shadow-retrieval-pre.js`、`lib/context-host-pre.js`
|
|
18
|
-
- 关键词:`async recall(`、`defineTool('
|
|
18
|
+
- 关键词:`async recall(`、`defineTool('memory_recall'`、`engine.recall(`、`lexicalSearch`、`buildQueryPlan`、`D6_FUSION_WEIGHTS_PRE_V1`、`fuseD6Pre`、`SHADOW_GATE_POLICY_PRE_V1`
|
|
19
19
|
- 必须先确认:① `recall()` 真实行号与完整函数体 ② 当前召回走的是 `lexicalSearch` 还是别的函数 ③ C2 引擎实例在 `index.js` 中如何持有(字段名)④ 是否已有 `scope='sessions'` 走 host 的分支
|
|
20
20
|
|
|
21
21
|
**改动边界**:
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**目标**:两个独立小缺陷 ① 账本标题重复(最近 6 个中 3 个含两个 `# 交接账本` 标题行、时间戳不一致,解析会取到错的)② `PLAN.md` 退化成日志(并列堆积 2.2.5/2.2.6 状态与历史踩坑,无老化)。
|
|
6
6
|
|
|
7
|
-
**涉及功能模块**:`
|
|
7
|
+
**涉及功能模块**:`memory_note` 的 `kind=handoff` 分支;白板归档(复用既有 PLAN archive 机制)。
|
|
8
8
|
|
|
9
9
|
**验收标准**:
|
|
10
10
|
1. 追加写入前检测已存在标题则跳过(或解析取最后一个标题,二选一并断言)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
你是 dsh-auto-memory 的发版执行子代理。工作目录:`D:\dsh-auto-memory
|
|
9
|
+
你是 dsh-auto-memory 的发版执行子代理。工作目录:`D:\dsh-auto-memory`(开发树,即唯一工作树;发布基座在 `D:\dsh_debug\_publish_dsh-auto-memory`,下称 REL)。**本次要发布的版本号:`<ver>`(由主对话填入,形如 2.5.0)。**
|
|
10
10
|
|
|
11
11
|
## 硬性禁令(违反任何一条=任务失败)
|
|
12
12
|
|
|
@@ -63,7 +63,7 @@ node tools\release.mjs <ver> --dry-run
|
|
|
63
63
|
node tools\release.mjs <ver>
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
复核输出含 `开发树版本回写: … → <ver>`。构建会写 REL
|
|
66
|
+
复核输出含 `开发树版本回写: … → <ver>`。构建会写 REL 树。**构建后开发树的 `package.json` 已被回写为新版本 → 立即补一笔提交**(v2.5.0 教训:不补会留下脏文件,污染下一次发版的脏树闸门):
|
|
67
67
|
|
|
68
68
|
```powershell
|
|
69
69
|
cd D:\dsh-auto-memory
|
|
@@ -115,11 +115,11 @@ Invoke-RestMethod 'https://registry.npmjs.org/@a9i5k4%2Fdsh-auto-memory/latest'
|
|
|
115
115
|
## 回报格式(原样 JSON,不追加散文)
|
|
116
116
|
|
|
117
117
|
```json
|
|
118
|
-
{ "ok": true, "version": "<ver>", "pre_sha": "
|
|
118
|
+
{ "ok": true, "version": "<ver>", "pre_sha": "<开发树 commit 短 sha>", "rel_sha": "<REL commit 短 sha>", "tag": "v<ver>", "npm_latest": "<ver>", "failed_step": "", "error_tail": "" }
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
失败时:`ok:false`,`failed_step` 填阶段号(0/1/2/3/4/5/6/7/8;dry-run 闸门不过记 3),`error_tail` 贴**最后 ≤20 行**原始报错(凭据替换为 `<redacted>`)。已知会出现且**不算失败**的情况:无。任何意外都按失败回报,由主对话决定处置。
|
|
122
122
|
|
|
123
123
|
---
|
|
124
124
|
|
|
125
|
-
*回滚提示(供主对话,子代理不执行):未 push/publish
|
|
125
|
+
*回滚提示(供主对话,子代理不执行):未 push/publish 前一切可回滚(开发树 `git reset`、REL 线 `git reset` + `git tag -d`);publish 后不可撤,只能发 patch。*
|
|
@@ -142,7 +142,7 @@ dsh web --no-open --port 0 # 需要指定端口时(0 = 系统分配空闲
|
|
|
142
142
|
- **证据**:注入内容截图 + 日志片段
|
|
143
143
|
|
|
144
144
|
### L2 语义检索
|
|
145
|
-
- **步骤**:调 `
|
|
145
|
+
- **步骤**:调 `memory_recall`,查一个**词法不重合但语义相关**的查询(记忆里写"npm 发布报 ENEEDAUTH",查"发布凭证问题")
|
|
146
146
|
- **通过**:能召回。**若失败 → 切 `legacy` 融合再测对比**
|
|
147
147
|
- **判定**:legacy 正常而 rrf 失败 = **P8 融合回归,停止**
|
|
148
148
|
- **证据**:两次返回的 top-5 `id` 序列
|
package/lib/acceptance.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* acceptance-pre —— P5 分档运行验收清单(2026-09-16,
|
|
2
|
+
* acceptance-pre —— P5 分档运行验收清单(2026-09-16, acceptance_pre_v1)。
|
|
3
3
|
*
|
|
4
4
|
* 权威依据: MASTER-PLAN §Phase 5 + TODO-GRAPH V2-P5 卡。
|
|
5
5
|
* 核心纪律(卡内原文): **发布材料逐项记录通过/失败/未执行 —— 不把「没测试环境」写成「已验收」**;
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
* 兼容档(compat)实测门: 未登记设备/负载数据 ⇒ 兼容项强制 not-run, 不可手工标 pass。
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
export const ACCEPTANCE_VERSION = '
|
|
13
|
+
export const ACCEPTANCE_VERSION = 'acceptance_pre_v1'
|
|
14
14
|
|
|
15
15
|
/** V2-P5 验收清单(必需项与依据)。 */
|
|
16
|
-
export const
|
|
16
|
+
export const ACCEPTANCE_ITEMS_PRE_V1 = Object.freeze([
|
|
17
17
|
{ id: 'T6-1', required: true, desc: '兼容配置拦截所有生成式模型调用(调用数=0), 目录/词法/展开通过' },
|
|
18
18
|
{ id: 'T6-2', required: true, desc: '前台返回时间与后台完成时间分开测' },
|
|
19
19
|
{ id: 'T6-3', required: true, desc: '资源界限事前登记(CPU/GPU、前台/后台分别登记)' },
|
|
@@ -28,7 +28,7 @@ export const ACCEPTANCE_ITEMS_V1 = Object.freeze([
|
|
|
28
28
|
*/
|
|
29
29
|
export function createAcceptanceLedgerPre() {
|
|
30
30
|
const entries = new Map() // id → {status, evidence, note, at}
|
|
31
|
-
for (const item of
|
|
31
|
+
for (const item of ACCEPTANCE_ITEMS_PRE_V1) entries.set(item.id, { status: 'not-run', evidence: '', note: '', at: 0 })
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* 登记一项结果。fail-closed 规则:
|
|
@@ -36,7 +36,7 @@ export function createAcceptanceLedgerPre() {
|
|
|
36
36
|
* - 非法状态名按 not-run 处理(不抛错, 但在 note 里如实标记 invalid)。
|
|
37
37
|
*/
|
|
38
38
|
function recordAcceptancePre(id, status, { evidence = '', note = '' } = {}) {
|
|
39
|
-
const item =
|
|
39
|
+
const item = ACCEPTANCE_ITEMS_PRE_V1.find((x) => x.id === id)
|
|
40
40
|
if (!item) return { ok: false, reason: 'unknown-item' }
|
|
41
41
|
let st = (status === 'pass' || status === 'fail') ? status : 'not-run'
|
|
42
42
|
let n = note
|
|
@@ -52,7 +52,7 @@ export function createAcceptanceLedgerPre() {
|
|
|
52
52
|
|
|
53
53
|
/** 汇总: release-ready 仅当全部必需项 pass。 */
|
|
54
54
|
function acceptanceSummaryPre() {
|
|
55
|
-
const items =
|
|
55
|
+
const items = ACCEPTANCE_ITEMS_PRE_V1.map((item) => ({ ...item, ...entries.get(item.id) }))
|
|
56
56
|
const passed = items.filter((x) => x.status === 'pass').length
|
|
57
57
|
const failed = items.filter((x) => x.status === 'fail')
|
|
58
58
|
const notRun = items.filter((x) => x.status === 'not-run')
|
package/lib/activation-host.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { memoryDir } from './datadir.js'
|
|
1
2
|
/**
|
|
2
3
|
* M6-3 Surface Adapter(docs/M6-CONTRACT.md §7-§11,§13 M6-3)。
|
|
3
4
|
* 桥接 lib/index.js(pre-step 生命周期/systemPrompt surface/调试路由)与 M6-1/2 纯核心:
|
|
@@ -5,7 +6,7 @@
|
|
|
5
6
|
* surface=systemPrompt.context(user-role 快照追加历史尾部);pre-step/user-message patch
|
|
6
7
|
* 不存在 → capability='dynamic-context';连 context 都没有 → 'none'(降级 Shadow,不标 delivered)。
|
|
7
8
|
* - pre-step 时序(§8):bumpStep→setCursor→claim(四重门);claimed packet 缓存于 runtime 态。
|
|
8
|
-
* - 渲染即投递:专用 context 组件 'dsh:m6-reference-tail' 的 text() 重渲染并校验 exactDigest,
|
|
9
|
+
* - 渲染即投递:专用 context 组件 'dsh:m6-reference-tail-pre' 的 text() 重渲染并校验 exactDigest,
|
|
9
10
|
* 一致则返回尾注文本(=已实际进入 messages)并 markDelivered + 异步创建 seen evidence;
|
|
10
11
|
* systemPrompt.section 永不承载动态 tail。
|
|
11
12
|
* 默认关闭(associativeMemoryEnabled ∧ activationInboxEnabled 双门);activationSource='fake' 为
|
|
@@ -13,10 +14,10 @@
|
|
|
13
14
|
* 接收 worker 帧并走现有 validator/inbox/pre-step claim(M7-1)。无 spawn/net/http;UTF-8 无 BOM。
|
|
14
15
|
*/
|
|
15
16
|
import {
|
|
16
|
-
buildReferenceTailPacketPre, renderReferenceTail, computeExactDigest,
|
|
17
|
-
|
|
17
|
+
buildReferenceTailPacketPre, renderReferenceTail, computeExactDigest, TAIL_MARKER_LINE_PRE_V1,
|
|
18
|
+
REFERENCE_TAIL_BUDGET_PRE_V1, ACTIVATION_POLICY_VERSION,
|
|
18
19
|
} from './activation-inbox.js'
|
|
19
|
-
import { createActivationInboxPre, ActivationInboxRegistry,
|
|
20
|
+
import { createActivationInboxPre, ActivationInboxRegistry, REFERENCE_TAIL_COOLDOWN_STEPS_PRE_V1 } from './activation-inbox-state.js'
|
|
20
21
|
import { createAccessEvidencePre } from './context-bridge.js'
|
|
21
22
|
import path from 'node:path'
|
|
22
23
|
import { resolveDshHomeForEnginePre } from './dsh-home.js'
|
|
@@ -24,17 +25,17 @@ import { buildSourceCatalog, loadCorpusSnapshot, CorpusRegistry, canonicalize }
|
|
|
24
25
|
import { resolveProcedureInjectEnabledPre } from './procedure-switch.js'
|
|
25
26
|
|
|
26
27
|
/** §11 capability 快照版本。 */
|
|
27
|
-
export const
|
|
28
|
+
export const CAPABILITY_SNAPSHOT_PRE_V1 = 'capability_pre_v1'
|
|
28
29
|
|
|
29
30
|
/** §11 capability 检测:按宿主提供的 surface 形状决定 packetPatch,禁止按模型名硬编码。 */
|
|
30
31
|
export function detectPacketCapabilityPre(ctxLike) {
|
|
31
32
|
const sp = ctxLike && ctxLike.systemPrompt
|
|
32
33
|
const hasContext = !!(sp && typeof sp.context === 'function')
|
|
33
34
|
return {
|
|
34
|
-
capabilityVersion:
|
|
35
|
+
capabilityVersion: CAPABILITY_SNAPSHOT_PRE_V1,
|
|
35
36
|
packetPatch: hasContext ? 'dynamic-context' : 'none',
|
|
36
37
|
includeRuntimeContext: false,
|
|
37
|
-
maxPacketBytes:
|
|
38
|
+
maxPacketBytes: REFERENCE_TAIL_BUDGET_PRE_V1.maxPacketBytes,
|
|
38
39
|
supportsDeliveryAck: true, // context text 返回非空即证明进入 messages,可同步 ack
|
|
39
40
|
}
|
|
40
41
|
}
|
|
@@ -43,7 +44,7 @@ export function createActivationHost(opts = {}) {
|
|
|
43
44
|
const engine = opts.engine
|
|
44
45
|
if (!engine) throw new Error('activation-host: engine required')
|
|
45
46
|
const registry = new ActivationInboxRegistry()
|
|
46
|
-
const corpusRegistry = new CorpusRegistry({ sidecarDir: path.join(
|
|
47
|
+
const corpusRegistry = new CorpusRegistry({ sidecarDir: path.join(memoryDir('index', dshHome), 'files') })
|
|
47
48
|
const runtimeState = new Map() // runtime.key → {step, claimed:{packet, inbox}|null, identity:{sessionId,workspaceKey}|null}
|
|
48
49
|
// ★多工作区适配(2026-09-17):以下两处此前是**单槽**(一个变量只装"最后写入者")。
|
|
49
50
|
// 症状:会话 A 投递 → 槽里是 A;会话 B(或用户点开另一个工作区触发 B)投递 → 槽里变 B;
|
|
@@ -56,7 +57,7 @@ export function createActivationHost(opts = {}) {
|
|
|
56
57
|
// 现补 `volatileDropped` 计数并具名化上限。
|
|
57
58
|
const volatileEvents = [] // ≤16 最小投影
|
|
58
59
|
let volatileDropped = 0
|
|
59
|
-
const
|
|
60
|
+
const VOLATILE_MAX_PRE_V1 = 16
|
|
60
61
|
const stats = { injected: 0, injectedAccepted: 0, injectedRejected: 0, claims: 0, claimFails: 0, rendered: 0, delivered: 0, seenCreated: 0, seenSkippedNoProv: 0, errors: 0 }
|
|
61
62
|
|
|
62
63
|
function effectiveEnabled() {
|
|
@@ -82,7 +83,7 @@ export function createActivationHost(opts = {}) {
|
|
|
82
83
|
}
|
|
83
84
|
function pushEvent(entry) {
|
|
84
85
|
volatileEvents.push({ at: Date.now(), ...entry })
|
|
85
|
-
if (volatileEvents.length >
|
|
86
|
+
if (volatileEvents.length > VOLATILE_MAX_PRE_V1) {
|
|
86
87
|
volatileEvents.shift()
|
|
87
88
|
// ★#84:丢弃必须留痕(否则「看不到事件」无法区分「没产生」与「被挤掉」)
|
|
88
89
|
volatileDropped++
|
|
@@ -441,7 +442,7 @@ export function createActivationHost(opts = {}) {
|
|
|
441
442
|
}
|
|
442
443
|
|
|
443
444
|
/**
|
|
444
|
-
* 专用渲染面(dsh:m6-reference-tail 的 text()):重渲染 claimed packet 并校验 exactDigest,
|
|
445
|
+
* 专用渲染面(dsh:m6-reference-tail-pre 的 text()):重渲染 claimed packet 并校验 exactDigest,
|
|
445
446
|
* 一致 → 返回尾注文本 + markDelivered + 异步 seen;不一致/未声明 → 返回空串(零注入)。
|
|
446
447
|
*/
|
|
447
448
|
function renderTailFor(agent) {
|
|
@@ -453,7 +454,7 @@ export function createActivationHost(opts = {}) {
|
|
|
453
454
|
if (!st || !st.claimed) return ''
|
|
454
455
|
const { packet, inbox } = st.claimed
|
|
455
456
|
// skill 必须与 packet 构建时同源传入:渲染器据此复现逐字节一致的文本,exactDigest 才对得上
|
|
456
|
-
const re = renderReferenceTail(packet.references, { reason: packet.triggerReason, budgetBytes:
|
|
457
|
+
const re = renderReferenceTail(packet.references, { reason: packet.triggerReason, budgetBytes: REFERENCE_TAIL_BUDGET_PRE_V1.maxPacketBytes, skill: packet.skill })
|
|
457
458
|
if (!re.ok || computeExactDigest(re.text) !== packet.exactDigest) {
|
|
458
459
|
stats.errors++
|
|
459
460
|
pushEvent({ kind: 'render', reason: 'digest-mismatch' })
|
|
@@ -502,7 +503,7 @@ export function createActivationHost(opts = {}) {
|
|
|
502
503
|
/** §11 capability(按当前宿主形状);Host 无 ctx 引用,由 index.js 注入一次。 */
|
|
503
504
|
let capability = null
|
|
504
505
|
function initCapability(ctxLike) { capability = detectPacketCapabilityPre(ctxLike); return capability }
|
|
505
|
-
function getCapability() { return capability || { capabilityVersion:
|
|
506
|
+
function getCapability() { return capability || { capabilityVersion: CAPABILITY_SNAPSHOT_PRE_V1, packetPatch: 'none', supportsDeliveryAck: false } }
|
|
506
507
|
|
|
507
508
|
function debugView() {
|
|
508
509
|
if (!effectiveEnabled()) return { enabled: false }
|
|
@@ -510,7 +511,7 @@ export function createActivationHost(opts = {}) {
|
|
|
510
511
|
return {
|
|
511
512
|
enabled: true,
|
|
512
513
|
activationPolicyVersion: ACTIVATION_POLICY_VERSION,
|
|
513
|
-
cooldownSteps:
|
|
514
|
+
cooldownSteps: REFERENCE_TAIL_COOLDOWN_STEPS_PRE_V1,
|
|
514
515
|
capability: cap,
|
|
515
516
|
sourceMode: sourceMode(),
|
|
516
517
|
// 多工作区适配(2026-09-17):不再返回"最后一个写入者"的 miv,而是按工作区分片的映射。
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import {
|
|
14
14
|
validateActivationRequestPre, buildReferenceTailPacketPre, isExpired,
|
|
15
|
-
|
|
15
|
+
REFERENCE_TAIL_BUDGET_PRE_V1, ACTIVATION_POLICY_VERSION, DELIVERY_STATES_PRE_V1,
|
|
16
16
|
} from './activation-inbox.js'
|
|
17
17
|
|
|
18
18
|
/** cooldown 步数策略(冻结;投递后冷却)。 */
|
|
19
|
-
export const
|
|
19
|
+
export const REFERENCE_TAIL_COOLDOWN_STEPS_PRE_V1 = 2
|
|
20
20
|
|
|
21
21
|
const OFFER_REASONS = Object.freeze([
|
|
22
22
|
'pending', 'replaced', 'duplicate-packet', 'duplicate-activation', 'duplicate-observation',
|
|
@@ -158,11 +158,11 @@ export function createActivationInboxPre(opts = {}) {
|
|
|
158
158
|
claimedPacketId = null
|
|
159
159
|
deliveredIds.add(packetId)
|
|
160
160
|
deliveredOrder.push(packetId)
|
|
161
|
-
while (deliveredOrder.length >
|
|
161
|
+
while (deliveredOrder.length > REFERENCE_TAIL_BUDGET_PRE_V1.deliveredIdsCapacity) {
|
|
162
162
|
const oldest = deliveredOrder.shift()
|
|
163
163
|
deliveredIds.delete(oldest)
|
|
164
164
|
}
|
|
165
|
-
cooldownUntilStep = nowStep +
|
|
165
|
+
cooldownUntilStep = nowStep + REFERENCE_TAIL_COOLDOWN_STEPS_PRE_V1
|
|
166
166
|
lastDeliveredAtStep = nowStep
|
|
167
167
|
stats.delivered++
|
|
168
168
|
return { ok: true, packetId, cooldownUntilStep }
|