@kira905/dsh-memory-toolkit 0.0.0-stage → 0.1.1

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.
Files changed (132) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +661 -0
  3. package/README.en.md +110 -0
  4. package/README.md +102 -2
  5. package/dsh-memory-local/FORK-BASE.json +24 -0
  6. package/dsh-memory-local/README.md +113 -0
  7. package/dsh-memory-local/build.mjs +101 -0
  8. package/dsh-memory-local/cordis.patch.yml +20 -0
  9. package/dsh-memory-local/deploy.mjs +306 -0
  10. package/dsh-memory-local/entity-status.mjs +75 -0
  11. package/dsh-memory-local/lib/bridge.mjs +108 -0
  12. package/dsh-memory-local/lib/host-adapter.js +1171 -0
  13. package/dsh-memory-local/lib/index.d.ts +128 -0
  14. package/dsh-memory-local/lib/index.js +944 -0
  15. package/dsh-memory-local/lib/injector.mjs +400 -0
  16. package/dsh-memory-local/lib/memory-read.mjs +116 -0
  17. package/dsh-memory-local/lib/module-gate.mjs +68 -0
  18. package/dsh-memory-local/lib/pointer.mjs +152 -0
  19. package/dsh-memory-local/lib/prod-gate.mjs +121 -0
  20. package/dsh-memory-local/lib/recall-log.mjs +118 -0
  21. package/dsh-memory-local/lib/recall.mjs +192 -0
  22. package/dsh-memory-local/lib/schema-migrate.mjs +365 -0
  23. package/dsh-memory-local/lib/user-message.mjs +32 -0
  24. package/dsh-memory-local/lib/vectors-read.mjs +110 -0
  25. package/dsh-memory-local/package.json +51 -0
  26. package/dsh-memory-local/restore.mjs +259 -0
  27. package/dsh-memory-local/rollback-injector-fix.mjs +166 -0
  28. package/dsh-memory-local/src/bridge.mjs +108 -0
  29. package/dsh-memory-local/src/host-adapter.js +1171 -0
  30. package/dsh-memory-local/src/index.d.ts +128 -0
  31. package/dsh-memory-local/src/index.js +944 -0
  32. package/dsh-memory-local/src/injector.mjs +400 -0
  33. package/dsh-memory-local/src/memory-read.mjs +116 -0
  34. package/dsh-memory-local/src/module-gate.mjs +68 -0
  35. package/dsh-memory-local/src/pointer.mjs +152 -0
  36. package/dsh-memory-local/src/recall-log.mjs +118 -0
  37. package/dsh-memory-local/src/recall.mjs +192 -0
  38. package/dsh-memory-local/src/schema-migrate.mjs +365 -0
  39. package/dsh-memory-local/src/user-message.mjs +32 -0
  40. package/dsh-memory-local/src/vectors-read.mjs +110 -0
  41. package/dsh-memory-local/test/fixtures-s2b.mjs +216 -0
  42. package/dsh-memory-local/test/probe-entity.mjs +170 -0
  43. package/dsh-memory-local/test/regression.mjs +270 -0
  44. package/dsh-memory-local/test/s2b.test.mjs +568 -0
  45. package/dsh-memory-local/test/schema-migrate.test.mjs +334 -0
  46. package/dsh-memory-local/test/test-adapter-converge.mjs +127 -0
  47. package/dsh-memory-local/test/visible-injections.test.mjs +239 -0
  48. package/dsh-memory-local/verify-after-restart.mjs +181 -0
  49. package/lib/deploy-guard.mjs +391 -0
  50. package/lib/guard-http.mjs +93 -0
  51. package/lib/pitfall-form-map.mjs +130 -0
  52. package/lib/pitfall-score.mjs +185 -0
  53. package/lib/session-file-name.mjs +160 -0
  54. package/lib/zstd-frames.mjs +78 -0
  55. package/memory-db-tools/README.md +68 -0
  56. package/memory-db-tools/_test/test-memory-scope.mjs +302 -0
  57. package/memory-db-tools/audit-analyze.mjs +352 -0
  58. package/memory-db-tools/audit-dump-ids.mjs +245 -0
  59. package/memory-db-tools/audit-export.mjs +270 -0
  60. package/memory-db-tools/audit-hit-probe.mjs +227 -0
  61. package/memory-db-tools/audit-ledger-probe.mjs +236 -0
  62. package/memory-db-tools/audit-persona-overlap.mjs +277 -0
  63. package/memory-db-tools/audit-struct-probe.mjs +213 -0
  64. package/memory-db-tools/audit-verify-unchanged.mjs +276 -0
  65. package/memory-db-tools/check-memory-db.mjs +8 -0
  66. package/memory-db-tools/dump-memory-db.mjs +12 -0
  67. package/memory-db-tools/lib/memory-scope.mjs +446 -0
  68. package/memory-db-tools/list-memory-summary.mjs +477 -0
  69. package/memory-db-tools/memory-identity-check.mjs +101 -0
  70. package/memory-db-tools/memory-schema-migrate.mjs +290 -0
  71. package/memory-db-tools/memory-scope-fixture.mjs +197 -0
  72. package/memory-db-tools/read-memories.mjs +26 -0
  73. package/memory-db-tools/read-memory-db.mjs +20 -0
  74. package/memory-db-tools/refine-memories.mjs +247 -0
  75. package/memory-db-tools/show-mem-times.mjs +22 -0
  76. package/memory-engine/README.md +70 -0
  77. package/memory-engine/bench/bench.mjs +221 -0
  78. package/memory-engine/cli/distill-rollback.mjs +86 -0
  79. package/memory-engine/cli/distill.mjs +156 -0
  80. package/memory-engine/cli/doc-index-rebuild.mjs +155 -0
  81. package/memory-engine/cli/doc-index.mjs +48 -0
  82. package/memory-engine/cli/domain-tags.mjs +251 -0
  83. package/memory-engine/cli/pitfall-hook.mjs +91 -0
  84. package/memory-engine/cli/recall.mjs +132 -0
  85. package/memory-engine/cli/selfcheck.mjs +57 -0
  86. package/memory-engine/cli/serve-start.mjs +247 -0
  87. package/memory-engine/cli/sweep.mjs +58 -0
  88. package/memory-engine/cli/sync.mjs +69 -0
  89. package/memory-engine/lib/cli-util.mjs +197 -0
  90. package/memory-engine/lib/config.mjs +135 -0
  91. package/memory-engine/lib/dirty-ledger.mjs +174 -0
  92. package/memory-engine/lib/distill-rollback.mjs +178 -0
  93. package/memory-engine/lib/distill.mjs +898 -0
  94. package/memory-engine/lib/doc-index-store.mjs +325 -0
  95. package/memory-engine/lib/doc-index.mjs +529 -0
  96. package/memory-engine/lib/doc-scan.mjs +271 -0
  97. package/memory-engine/lib/doc-summarize.mjs +305 -0
  98. package/memory-engine/lib/domain-tags.mjs +429 -0
  99. package/memory-engine/lib/embedder.mjs +242 -0
  100. package/memory-engine/lib/hashes.mjs +12 -0
  101. package/memory-engine/lib/memory-source.mjs +127 -0
  102. package/memory-engine/lib/pitfall-source.mjs +170 -0
  103. package/memory-engine/lib/policy-source.mjs +371 -0
  104. package/memory-engine/lib/recall.mjs +331 -0
  105. package/memory-engine/lib/selfcheck.mjs +131 -0
  106. package/memory-engine/lib/sweep.mjs +159 -0
  107. package/memory-engine/lib/sync.mjs +180 -0
  108. package/memory-engine/lib/tick-hook.mjs +218 -0
  109. package/memory-engine/lib/vectors-store.mjs +292 -0
  110. package/memory-engine/package-lock.json +1086 -0
  111. package/memory-engine/package.json +22 -0
  112. package/memory-engine/serve.mjs +171 -0
  113. package/memory-engine/test/01-store.test.mjs +127 -0
  114. package/memory-engine/test/02-sync.test.mjs +196 -0
  115. package/memory-engine/test/03-sweep.test.mjs +145 -0
  116. package/memory-engine/test/04-recall.test.mjs +214 -0
  117. package/memory-engine/test/05-selfcheck.test.mjs +175 -0
  118. package/memory-engine/test/06-doc-index.test.mjs +928 -0
  119. package/memory-engine/test/07-domain-tags.test.mjs +298 -0
  120. package/memory-engine/test/08-distill.test.mjs +686 -0
  121. package/memory-engine/test/09-pitfall-source.test.mjs +365 -0
  122. package/memory-engine/test/10-tick-hook.test.mjs +252 -0
  123. package/memory-engine/test/11-policy-source.test.mjs +224 -0
  124. package/memory-engine/test/_tickhook-worker.mjs +56 -0
  125. package/memory-engine/test/fixtures.mjs +205 -0
  126. package/memory-engine/test/harness.mjs +73 -0
  127. package/memory-engine/test/run.mjs +35 -0
  128. package/memory-engine/tools/bridge-smoke.mjs +80 -0
  129. package/memory-engine/tools/fetch-model.mjs +128 -0
  130. package/memory-engine/tools/smoke-recall.mjs +76 -0
  131. package/package.json +53 -4
  132. package/persona-memory-audit.mjs +217 -0
package/README.en.md ADDED
@@ -0,0 +1,110 @@
1
+ # dsh-memory-toolkit
2
+
3
+ **Memory-side tooling for DSH (DeepSeek Harness).** A standalone vector memory engine, a read-only
4
+ memory-database audit toolkit, a self-maintained fork of the local memory plugin, and a tiny
5
+ persona ↔ memory audit.
6
+
7
+ All four pieces come from one self-hosted workflow, split out so they can be used together or on their own:
8
+ **the engine decides what to remember and how to find it again; the toolkit makes it visible and
9
+ fixable; the plugin wires it into a session.**
10
+
11
+ ---
12
+
13
+ ## 1. What's inside
14
+
15
+ | Directory | What it is | Form |
16
+ |---|---|---|
17
+ | [`memory-engine/`](./memory-engine/README.md) | Memory engine (offline layer): standalone vector store · incremental sync · hash-rotation fallback sweep · hybrid recall (vector + FTS5 + RRF) · document index · startup self-check · local encoding bridge | plain Node ESM + `node:sqlite` |
18
+ | [`memory-db-tools/`](./memory-db-tools/README.md) | Memory database toolkit: read-only export / six-way audit analysis / structure probe / feature-word probe / persona overlap / board-ledger probe / zero-write proof / new-session briefing | a set of standalone CLIs |
19
+ | [`dsh-memory-local/`](./dsh-memory-local/README.md) | Local memory plugin: a self-maintained fork of upstream `dsh-memory` (cross-session memory + recall prompt section + pointer injection), with build / idempotent deploy / one-command rollback / post-deploy self-check | DSH plugin |
20
+ | [`persona-memory-audit.mjs`](./persona-memory-audit.mjs) | Persona ↔ memory audit: pins down "persona body size" and "memory visibility" and reports red past thresholds | single-file CLI |
21
+ | [`lib/`](./lib) | Zero-dependency shared bits (argument allow-list / HTTP liveness judgement / zstd frames / session file names / pitfall scoring) | pure modules |
22
+
23
+ ## 2. Requirements
24
+
25
+ - **Node.js ≥ 22** (built-in `node:sqlite`, ESM)
26
+ - Windows / Linux / macOS. Every default path is derived from **environment variables or the current
27
+ working directory** — there are no hard-coded machine paths in this repo
28
+ - Local vector encoding in `memory-engine/` additionally needs `@huggingface/transformers` (optional)
29
+
30
+ ## 3. Install
31
+
32
+ ```bash
33
+ git clone https://github.com/kira905/dsh-memory-toolkit.git
34
+ cd dsh-memory-toolkit
35
+ npm install # the root package has no runtime dependencies
36
+ ```
37
+
38
+ For local ONNX vector encoding (optional):
39
+
40
+ ```bash
41
+ cd memory-engine
42
+ npm install # pulls @huggingface/transformers (large, 300+ MB)
43
+ ```
44
+
45
+ You can skip it entirely: the engine also supports an HTTP encoding bridge and a pure FTS5 fallback path.
46
+
47
+ ## 4. Quick start
48
+
49
+ ```bash
50
+ # ① Toolkit usage and options (zero side effects)
51
+ node memory-db-tools/audit-export.mjs --help
52
+
53
+ # ② Persona ↔ memory audit (read-only)
54
+ node persona-memory-audit.mjs --help
55
+
56
+ # ③ New-session briefing (read-only)
57
+ node memory-db-tools/list-memory-summary.mjs --help
58
+
59
+ # ④ Engine startup self-check (run npm install inside memory-engine/ first)
60
+ cd memory-engine && node cli/selfcheck.mjs --json
61
+ ```
62
+
63
+ A typical **quarterly memory audit** (read-only; artifacts go where you point them):
64
+
65
+ ```bash
66
+ node memory-db-tools/audit-export.mjs --out ./_audit/memories.json
67
+ node memory-db-tools/audit-analyze.mjs --in ./_audit/memories.json --out ./_audit
68
+ node memory-db-tools/audit-struct-probe.mjs --in ./_audit/memories.json
69
+ node memory-db-tools/audit-verify-unchanged.mjs --baseline ./_audit/memories.json --expect-unchanged
70
+ ```
71
+
72
+ ## 5. Integration points with DSH
73
+
74
+ This repo runs **without** DSH, but three seams are deliberate:
75
+
76
+ | Seam | Notes |
77
+ |---|---|
78
+ | `DSH_HOME` (default `~/.dsh`) | Memory DB (`memory/memory.db`), vector store (`memory-vectors/`), presets (`.agent-presets/`) and profile overrides (`profiles/<profile>/cordis.patch.yml`) are all derived from it |
79
+ | Deployment shape of `dsh-memory-local/` | The plugin **occupies the upstream slot** `profiles/<profile>/node_modules/dsh-memory` (no new package name, no profile rewiring); in `cordis.patch.yml`, `insert.name` must stay `dsh-memory` |
80
+ | Environment injection | `MEMORY_ENGINE_*` (db / vectors / model / batch / recall), `DOC_INDEX_*` (document index scope), `DSH_ARCHIVE` (backup root), `DSH_PROD_ROOTS` (production-tree gate) |
81
+
82
+ ## 6. Data and safety
83
+
84
+ - **Read-only on the memory DB**: the engine and every `audit-*` tool open `memory.db` with
85
+ `readOnly: true`; the only write surfaces are the standalone vector store and output directories you pass in.
86
+ - **No telemetry, no exfiltration**; the only outbound calls are the LLM / embedding endpoints you enable yourself.
87
+ - **Credentials are read from environment variables or a local config file only**; no secrets are present in the code.
88
+ - **Production write gate**: restore / rollback style scripts refuse to touch a production tree unless
89
+ `--allow-production` is given (`--dry-run` is read-only and always allowed).
90
+
91
+ ## 7. License
92
+
93
+ **AGPL-3.0** (GNU Affero General Public License v3.0) — full text in [LICENSE](./LICENSE).
94
+
95
+ Free to use and modify for personal, educational and open-source projects. For **closed-source or
96
+ commercial** use (where AGPL's copyleft does not apply) please open an issue in
97
+ [Issues](https://github.com/kira905/dsh-memory-toolkit/issues) to obtain a **commercial license**.
98
+
99
+ > **Subtree exception**: `dsh-memory-local/` is a fork of upstream `dsh-memory` (MIT) and that subtree
100
+ > **keeps the upstream MIT license** (see its `package.json` `license` field and `FORK-BASE.json`).
101
+ > Everything else is original work, released under AGPL-3.0 + commercial licensing.
102
+
103
+ ## 8. Related repositories
104
+
105
+ - [`dsh-butler-archive`](https://github.com/kira905/dsh-butler-archive) — DSH autonomous-ops butler (archived)
106
+ - [`dsh-session-toolkit`](https://github.com/kira905/dsh-session-toolkit) — session titles / session hygiene
107
+ - [`dsh-ecosystem-panel`](https://github.com/kira905/dsh-ecosystem-panel) — ecosystem panel
108
+ - [`dsh-firstaid`](https://github.com/kira905/dsh-firstaid) — first-aid / rollback drills
109
+
110
+ Each companion repo is independent in scope, versioning and licensing.
package/README.md CHANGED
@@ -1,3 +1,103 @@
1
- # Temporary Holding Version
1
+ # dsh-memory-toolkit
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **DSH(DeepSeek Harness)生态的记忆面工具集** —— 一个独立向量记忆引擎、一套记忆库只读体检工具链、
4
+ 一个自持 fork 的本地记忆插件,以及一个 persona ↔ 记忆体检小工具。
5
+
6
+ 四件东西原本是同一套自用工作流的不同切面,抽出来独立成仓,可以单独用,也可以拼起来用:
7
+ **引擎负责"记什么、怎么找回来",工具链负责"看得见、改得动",插件负责"接进会话"。**
8
+
9
+ ---
10
+
11
+ ## 一、里面有什么
12
+
13
+ | 目录 | 是什么 | 形态 |
14
+ |---|---|---|
15
+ | [`memory-engine/`](./memory-engine/README.md) | 记忆引擎(离线层):独立矢量库 · 增量同步 · 兜底 hash 轮转 · 混合召回(向量 + FTS5 + RRF) · 文档索引 · 启动自检 · 本地编码桥 | 纯 Node ESM + `node:sqlite` |
16
+ | [`memory-db-tools/`](./memory-db-tools/README.md) | 记忆库工具集:只读导出 / 六项体检分析 / 结构探针 / 特征词探针 / 与 persona 的重合度 / 看板账本只读探针 / 零改动自证 / 新会话开工简报 | 一组独立 CLI |
17
+ | [`dsh-memory-local/`](./dsh-memory-local/README.md) | 本地记忆插件:上游 `dsh-memory` 的自持 fork(跨会话持久记忆 + 召回提示段 + 指针注入链),带构建 / 幂等部署 / 一键回滚 / 部署后自检 | DSH 插件 |
18
+ | [`persona-memory-audit.mjs`](./persona-memory-audit.mjs) | persona ↔ 记忆体检:把「persona 正文体积」与「记忆可见率」两项指标固定下来,超阈值即报红 | 单文件 CLI |
19
+ | [`lib/`](./lib) | 四件共用的无依赖小件(参数白名单 / HTTP 存活判据 / zstd 帧解析 / 会话文件名 / 坑库打分) | 纯函数模块 |
20
+
21
+ ## 二、环境要求
22
+
23
+ - **Node.js ≥ 22**(用到内置 `node:sqlite`,以及 ESM 顶层能力)
24
+ - 平台:Windows / Linux / macOS 均可;路径默认值一律从**环境变量或当前工作目录**推导,不含任何写死的机器路径
25
+ - `memory-engine/` 的**本地向量编码**额外需要 `@huggingface/transformers`(可选,见下)
26
+
27
+ ## 三、安装
28
+
29
+ ```bash
30
+ git clone https://github.com/kira905/dsh-memory-toolkit.git
31
+ cd dsh-memory-toolkit
32
+ npm install # 本仓根包零运行时依赖,此步只装元数据
33
+ ```
34
+
35
+ 要跑**本地向量编码**(`memory-engine` 的 ONNX 路径),再装它自己的依赖:
36
+
37
+ ```bash
38
+ cd memory-engine
39
+ npm install # 会拉 @huggingface/transformers(较大,约 300+ MB)
40
+ ```
41
+
42
+ 不想装这个依赖也可以:引擎的召回支持**HTTP 编码桥**(见下),以及纯 FTS5 的降级路径。
43
+
44
+ ## 四、快速开始(命令可直接照抄)
45
+
46
+ ```bash
47
+ # ① 体检工具链的用法与参数(零副作用,先看再跑)
48
+ node memory-db-tools/audit-export.mjs --help
49
+
50
+ # ② persona ↔ 记忆体检(只读;读 $DSH_HOME 下的 persona 与记忆库)
51
+ node persona-memory-audit.mjs --help
52
+
53
+ # ③ 新会话开工简报(只读:设备行 + 记忆清单 + pinned 全文)
54
+ node memory-db-tools/list-memory-summary.mjs --help
55
+
56
+ # ④ 记忆引擎的启动自检(需要先在 memory-engine/ 内 npm install)
57
+ cd memory-engine && node cli/selfcheck.mjs --json
58
+ ```
59
+
60
+ 一次典型的**季度记忆库体检**(全部只读,产物落你指定的目录):
61
+
62
+ ```bash
63
+ node memory-db-tools/audit-export.mjs --out ./_audit/memories.json
64
+ node memory-db-tools/audit-analyze.mjs --in ./_audit/memories.json --out ./_audit
65
+ node memory-db-tools/audit-struct-probe.mjs --in ./_audit/memories.json
66
+ node memory-db-tools/audit-verify-unchanged.mjs --baseline ./_audit/memories.json --expect-unchanged
67
+ ```
68
+
69
+ ## 五、与 DSH 的集成点
70
+
71
+ 本仓**不依赖 DSH 才能运行**,但下面三处是刻意的接缝:
72
+
73
+ | 接缝 | 说明 |
74
+ |---|---|
75
+ | `DSH_HOME`(缺省 `~/.dsh`) | 记忆库(`memory/memory.db`)、向量库(`memory-vectors/`)、preset(`.agent-presets/`)、profile 覆盖(`profiles/<profile>/cordis.patch.yml`)一律从它推导 |
76
+ | `dsh-memory-local/` 的部署形态 | 插件**占用上游包槽位** `profiles/<profile>/node_modules/dsh-memory`(不新增包名、不改 profile wiring),`cordis.patch.yml` 的 `insert.name` 必须保持 `dsh-memory` |
77
+ | 环境变量注入 | `MEMORY_ENGINE_*`(库/向量/模型/批大小/召回参数)、`DOC_INDEX_*`(文档索引扫描面)、`DSH_ARCHIVE`(备份落点)、`DSH_PROD_ROOTS`(生产树放行闸) |
78
+
79
+ ## 六、数据与安全
80
+
81
+ - **对记忆库只读**:引擎与全套 `audit-*` 工具打开 `memory.db` 一律 `readOnly: true`;唯一的写口是独立向量库与你自己指定的输出目录。
82
+ - **不收集、不外发**:没有任何遥测;唯一的外部网络调用是你主动启用的 LLM/编码端点。
83
+ - **凭据只从环境变量或本地配置文件读**,代码里没有、也不会写任何密钥。
84
+ - **生产写闸**:还原 / 回滚类脚本动到生产树前必须显式 `--allow-production`,否则拒跑(`--dry-run` 是只读档,不受限)。
85
+
86
+ ## 七、许可
87
+
88
+ **AGPL-3.0**(GNU Affero General Public License v3.0),全文见 [LICENSE](./LICENSE)。
89
+
90
+ 个人、学习、开源项目可自由使用与修改。若要在**闭源**或**商业场景**中使用(AGPL 的传染条款不适用),
91
+ 请在 [Issues](https://github.com/kira905/dsh-memory-toolkit/issues) 开一条说明用途,获取**商业授权**。
92
+
93
+ > **子树例外**:`dsh-memory-local/` 是上游 `dsh-memory`(MIT)的 fork,
94
+ > 该子树**保持上游 MIT 许可**(见其 `package.json` 的 `license` 字段与 `FORK-BASE.json`);
95
+ > 其余目录(引擎、工具链、共用件)为本项目原创,按 AGPL-3.0 + 商业授权双许可发布。
96
+
97
+ ## 八、相关仓
98
+
99
+ - [`dsh-butler-archive`](https://github.com/kira905/dsh-butler-archive) —— DSH 大管家(自主运维机制)归档仓
100
+ - [`dsh-session-toolkit`](https://github.com/kira905/dsh-session-toolkit) —— 会话标题 / 会话治理
101
+ - [`dsh-ecosystem-panel`](https://github.com/kira905/dsh-ecosystem-panel) —— 生态面板
102
+ - [`dsh-firstaid`](https://github.com/kira905/dsh-firstaid) —— 急救台 / 回滚演练
103
+ - 同属 DSH 生态的伴生组件各自独立仓、独立版本、许可各自独立。
@@ -0,0 +1,24 @@
1
+ {
2
+ "forkName": "dsh-memory-local",
3
+ "upstream": {
4
+ "name": "dsh-memory",
5
+ "version": "0.1.0",
6
+ "license": "MIT"
7
+ },
8
+ "source": {
9
+ "dir": "<DSH_HOME>/profiles/web/node_modules/dsh-memory",
10
+ "file": "lib/index.js",
11
+ "sha256": "494ca272f674918f5acfcf32327c164c6eba26fa08fc28bef50e085754c6f28c",
12
+ "bytes": 14224,
13
+ "lines": 421,
14
+ "dtsSha256": "471db6217fe4fc2ccc602a021efbc70f5a6490bd5d0c1e94123300d63e4dedf0",
15
+ "patchSha256": "1d34ead2d421cecce0d448131dc33e9223d2bcea3597d74d30911fe6ad1e7e99"
16
+ },
17
+ "forkedAt": "2026-09-20T16:15:20.970Z",
18
+ "note": [
19
+ "源码权威 = 本仓 tools/dsh-memory-local/src/;官方 lib/index.js 是 fork 的字节基线。",
20
+ "npm 分发包不含 TypeScript 源,故本 fork 以官方编译产物为源码基线,构建 = 语法校验 + 拷贝 + 指纹。",
21
+ "cordis.patch.yml 逐字节沿用上游:其 insert name 必须保持 `dsh-memory`,",
22
+ "因为 profile 的 bundle 名、patch insert name、.package-map.json 全部按该槽位解析(见 README §3)。"
23
+ ]
24
+ }
@@ -0,0 +1,113 @@
1
+ # dsh-memory-local
2
+
3
+ 自持 fork:官方 `dsh-memory` 插件(跨会话持久记忆 + `memory:recall` 提示段),加一层自研的指针注入链。
4
+ 本包是记忆引擎的**插件侧载体**:把独立向量库的记忆接进会话提示面。
5
+
6
+
7
+ > **首发范围**:源码自持 → 构建 → 幂等部署 → 一键回滚 → 部署后自检,以及 L2 模块登记。
8
+ > 指针注入逻辑见 `src/injector.mjs`(与骨架同批交付)。
9
+
10
+ ---
11
+
12
+ ## 1. fork 基点(FORK-BASE.json 为机器可读版本)
13
+
14
+ | 项 | 值 |
15
+ |---|---|
16
+ | 上游包 | `dsh-memory@0.1.0`(npm dist · MIT) |
17
+ | 基点文件 | `lib/index.js` —— 421 行(逐字节 sha256 记在 `FORK-BASE.json` 的 `source.sha256`) |
18
+ | 上游来源(只读) | `<DSH_HOME>/profiles/<profile>/node_modules/dsh-memory/` |
19
+ | fork 时间 | 2026-09-21 |
20
+
21
+
22
+ 上游 npm 包**只发布编译产物**(`lib/`,无 TypeScript 源,也不含 `src/`),所以本 fork 的
23
+ 「源码」= 官方 `lib/index.js` 逐字节 + 一段 `FORK NOTICE` 头注;构建不是编译,而是
24
+ **语法校验 + 拷贝 + 指纹**(见 §3)。
25
+
26
+ ## 2. 与官方的差异(当前 = 只有头注)
27
+
28
+ | 文件 | 差异 |
29
+ |---|---|
30
+ | `src/index.js` | 上游文件逐字节 + 顶部 19 行 `FORK NOTICE`。**函数体、工具定义、配置项一字未改**(`Compare-Object` 差异行 = 19,全部落在头注内) |
31
+ | `src/index.d.ts` | 逐字节同上游 |
32
+ | `cordis.patch.yml` | **逐字节同上游** —— 其中 `insert.name` 必须保持 `dsh-memory`(见 §4) |
33
+ | `package.json` | `name` → `dsh-memory-local`、`private: true`、**`dependencies` 置空**(零第三方依赖;`@deepseek-ai/schemastery` / `@deepseek-ai/dsh-tools` 由宿主主包的闭包在部署位置提供)、`scripts` 换成 build/test/deploy/verify |
34
+ | `src/injector.mjs` | fork 自研(指针注入链;上游没有这个文件)。**2026-10-09**:`visibleInjections()` 取事件面改「**新面优先 + 老线回落**」—— 主包 0.1.5-rc.2 起 `Session.events` 已移除,只能用 `eventAt(seq)`;老线(≤0.1.4 的 `session.events`)回落保留,两面都没则安全返回 `{count:0}`。⚠️ 主包 0.1.6 会再弃用 `seq`/`eventAt`/`snapshotEvents` ⇒ 升级时此处须再复测。回滚:`node rollback-injector-fix.mjs --target <home> --allow-production`(默认 dry-run) |
35
+
36
+ **零第三方依赖判据**:`package.json` 的 `dependencies` 为空对象;运行期只 import
37
+ `@deepseek-ai/schemastery`、`@deepseek-ai/dsh-tools`(宿主主包自带)与 node 内置模块
38
+ (`node:fs` / `node:path` / `node:sqlite`)。
39
+
40
+ ## 3. 目录与命令
41
+
42
+ ```
43
+ dsh-memory-local/
44
+ ├─ src/index.js 自持源码(官方基点 + FORK NOTICE)
45
+ ├─ src/index.d.ts
46
+ ├─ lib/ 构建产物(deploy 只搬这一层 + cordis.patch.yml + package.json)
47
+ ├─ cordis.patch.yml bundle patch(逐字节同上游)
48
+ ├─ FORK-BASE.json fork 基点元数据(上游 sha / 行数 / 来源 / 口径说明)
49
+ ├─ build.mjs 构建:断言基点 → node --check → 拷进 lib/ → 写 lib/.build-info.json
50
+ ├─ deploy.mjs 幂等部署进 <DSH_HOME>/profiles/<profile>/node_modules/dsh-memory
51
+ ├─ restore.mjs 原子还原上游原物(含 --self-test 沙箱演练 / --dry-run / --list)
52
+ ├─ verify-after-restart.mjs 部署后自检(只读)
53
+ └─ test/
54
+ ├─ probe-entity.mjs 部署位置加载探针:三工具 + memory:recall 段 + 真跑 write/search/forget
55
+ └─ regression.mjs 上游 vs fork「同输入同输出」逐步骤对照(行为一致判据)
56
+ ```
57
+
58
+ ```powershell
59
+ node build.mjs # 构建(--check 只校验不写 lib/)
60
+ node build.mjs --check
61
+
62
+ # 部署(--target 必填;目标是本机默认 home = 生产,须显式 --allow-production)
63
+ node deploy.mjs --target <隔离实例的 DSH_HOME>
64
+
65
+ # 自检(可带实例端口与日志文件)
66
+ node verify-after-restart.mjs --target <隔离实例的 DSH_HOME> --port <实例端口> --log-file <实例日志>
67
+
68
+ # 回滚(原子还原上游原物;先演练再动真)
69
+ node restore.mjs --self-test
70
+ node restore.mjs --target <隔离实例的 DSH_HOME> --dry-run
71
+ node restore.mjs --target <隔离实例的 DSH_HOME>
72
+
73
+ # 行为回归(fork 侧默认取隔离实例实体)
74
+ node test/regression.mjs
75
+ ```
76
+
77
+ ## 4. 部署形态:为什么占「上游槽位」
78
+
79
+ profile 的 `package.json`(`dsh.profile.bundles` 含 `dsh-memory`)、`node_modules/.package-map.json`
80
+ (`dsh-memory → ./dsh-memory`)与 bundle patch 的 `insert.name` **三处都按 `dsh-memory` 解析**。
81
+ 因此部署**不新增包名、不改 profile wiring**,而是**原地替换 `node_modules/dsh-memory` 实体**:
82
+
83
+ * 实体里的 `package.json` 写成**部署态**:`name` = `dsh-memory`、`version` = 上游版本(与 profile
84
+ 的 `dependencies` 声明一致),另加 `fork` 段记录真身(`dsh-memory-local@…`)、基点 sha、产物 sha、
85
+ 部署来源与时间 —— 自检与人工都据此判别「这是 fork 版」;
86
+ * `cordis.patch.yml` 的 `insert.name` 保持 `dsh-memory`(若改成 `dsh-memory-local`,
87
+ 解析会去找不存在的 `node_modules/dsh-memory-local`)。
88
+
89
+ 副作用:`deploy.mjs` **不写** profile `package.json`、**不写** `.package-map.json`、**不重启**任何 DSH。
90
+
91
+ ## 5. 备份与回滚
92
+
93
+ * 首次替换时,`deploy.mjs` 把上游原物**整份**归档到 `$DSH_ARCHIVE`(缺省 `<cwd>/_archive`)下:
94
+ `_archive\g24-s2a-memory-deploy-<stamp>\official-entity\` + `OFFICIAL-ENTITY.json`(逐文件 sha 清单);
95
+ * 之后重复 deploy 只追加 `DEPLOY-INFO-<stamp>.json`,**不覆盖**那份上游原物;
96
+ * `restore.mjs` 的还原源 = 上述目录(导出路径见 `--list`),
97
+ 还原前先把当前 fork 实体快照到 `_archive\g24-s2a-memory-prerestore-<stamp>\entity-before-restore\`
98
+ (还原动作自己也可被回看/再回滚),然后 `stage → 核 sha → 交换 → 复核`。
99
+
100
+ ## 6. 上游合并流程(将来升 `dsh-memory` 时)
101
+
102
+ 1. 取新版上游实体(另一份 npm 安装目录,或 `npm pack dsh-memory@<ver>` 解包);
103
+ 2. 重跑骨架步骤,让 `src/index.js` 重新等于「新版 + FORK NOTICE」(`FORK-BASE.json` 更新基点 sha);
104
+ 3. 用 `git diff --no-index <上游新 lib/index.js> <旧 src/index.js 去掉头注>` 的形式看**自己的本地改动**
105
+ (本地改动一律以 `FORK-EDIT(<date>):` 行注留在 `src/`,便于三方合并);
106
+ 4. `node build.mjs` → `node test/regression.mjs`(对照物换成新版上游实体)→ 隔离实例 `deploy.mjs` → `verify-after-restart.mjs`;
107
+ 5. 全绿才谈上生产;任一环红了就 `restore.mjs` 回滚到官方原物。
108
+
109
+ ## 7. 边界(本卡红线)
110
+
111
+ * 只做**隔离面**(独立 `DSH_HOME` + 非生产端口);生产实例的端口与生产 `profiles` 实体**一律不碰**;
112
+ * 不写 `memory.db`、不挂 tickd job、不改 `butler-autonomy.json`;
113
+ * `deploy.mjs` / `restore.mjs` 都**不重启 DSH**(要重启一律走 P0 闸门)。
@@ -0,0 +1,101 @@
1
+ /**
2
+ * build.mjs —— dsh-memory-local 的构建步骤(零依赖,node 原生)。
3
+ *
4
+ * 上游 npm 包只发布编译后的 JS(无 TypeScript 源),所以本 fork 的「源码」就是
5
+ * `src/index.js`(= 官方 lib/index.js + FORK NOTICE 头注)。构建因此是:
6
+ *
7
+ * 1) 断言 src/ 齐全、FORK NOTICE 在位、与 FORK-BASE.json 的基点一致;
8
+ * 2) `node --check` 对每个 JS 源码做语法校验(解析失败即拒绝产出);
9
+ * 3) 把 src/* 拷进 lib/(运行时实体目录,deploy.mjs 只搬 lib/ + cordis.patch.yml + package.json);
10
+ * 4) 写 lib/.build-info.json —— 源码 sha / 产物 sha / 基点 sha / 构建时间 / node 版本,
11
+ * 供 verify-after-restart.mjs 做「版本与 sha 对齐」断言。
12
+ *
13
+ * 幂等:产物字节一致时不重写文件(只刷新指纹文件)。
14
+ * 退出码:0 = 成功 / 1 = 构建失败(源缺失、语法错、基点不符)。
15
+ *
16
+ * 用法:node build.mjs [--check] (--check = 只校验不写 lib/,可当 CI 用)
17
+ */
18
+ import fs from 'node:fs'
19
+ import path from 'node:path'
20
+ import crypto from 'node:crypto'
21
+ import { spawnSync } from 'node:child_process'
22
+ import { fileURLToPath } from 'node:url'
23
+
24
+ const here = path.dirname(fileURLToPath(import.meta.url))
25
+ const srcDir = path.join(here, 'src')
26
+ const libDir = path.join(here, 'lib')
27
+ const checkOnly = process.argv.includes('--check')
28
+
29
+ const sha256 = (buf) => crypto.createHash('sha256').update(buf).digest('hex')
30
+ const rel = (p) => path.relative(here, p).replaceAll('\\', '/')
31
+
32
+ function fail(message) {
33
+ console.error(`[build] FAIL ${message}`)
34
+ process.exit(1)
35
+ }
36
+
37
+ // 1) 源与基点 -----------------------------------------------------------------
38
+ const forkBaseFile = path.join(here, 'FORK-BASE.json')
39
+ if (!fs.existsSync(forkBaseFile)) fail('FORK-BASE.json missing (run the fork skeleton step first)')
40
+ const forkBase = JSON.parse(fs.readFileSync(forkBaseFile, 'utf8'))
41
+ const entry = path.join(srcDir, 'index.js')
42
+ if (!fs.existsSync(entry)) fail('src/index.js missing')
43
+ const srcText = fs.readFileSync(entry, 'utf8')
44
+ if (!srcText.startsWith('/**\n * FORK NOTICE')) fail('src/index.js is missing the FORK NOTICE header')
45
+ if (!srcText.includes(forkBase.source.sha256)) fail('FORK NOTICE carries a base sha256 that does not match FORK-BASE.json')
46
+
47
+ // 2) 语法校验 -----------------------------------------------------------------
48
+ const sources = fs.readdirSync(srcDir).filter((n) => /\.(mjs|cjs|js)$/.test(n)).sort()
49
+ for (const name of sources) {
50
+ const full = path.join(srcDir, name)
51
+ const r = spawnSync(process.execPath, ['--check', full], { encoding: 'utf8' })
52
+ if (r.status !== 0) fail(`node --check failed for ${rel(full)}\n${(r.stderr ?? '').trim()}`)
53
+ }
54
+ console.log(`[build] syntax ok: ${sources.length} source file(s) -> ${sources.join(', ')}`)
55
+
56
+ // 3) 产出 ---------------------------------------------------------------------
57
+ // ⚠️ U3(2026-09-22):宿主适配层副本**不进 build 产出** —— 它由 tools\sync-host-adapter.mjs 生成,
58
+ // `src/` 与 `lib/` 各持一份、头部带各自的 target 标识(字节必然不同)。若 build 把 src 那份拷进
59
+ // `lib/`,lib 副本的头会变成 src 的 target ⇒ R5 立刻报 header-only-diff(lib 目标是同步器独占的)。
60
+ // 语法校验仍照跑(上面的 sources 未变),只有"拷贝"这一步跳过。
61
+ const GENERATED_BY_SYNC = new Set(['host-adapter.js'])
62
+ if (!fs.existsSync(path.join(libDir, 'host-adapter.js'))) {
63
+ fail('lib/host-adapter.js missing — 先跑宿主侧的 sync-host-adapter.mjs 生成(否则部署会 Cannot find module)')
64
+ }
65
+ const artifacts = sources.filter((name) => !GENERATED_BY_SYNC.has(name)).map((name) => ({
66
+ name,
67
+ from: path.join(srcDir, name),
68
+ to: path.join(libDir, name),
69
+ }))
70
+ // 类型声明随源码走(官方包 exports 的 types 指向它)
71
+ const dts = path.join(srcDir, 'index.d.ts')
72
+ if (fs.existsSync(dts)) artifacts.push({ name: 'index.d.ts', from: dts, to: path.join(libDir, 'index.d.ts') })
73
+
74
+ if (checkOnly) {
75
+ console.log('[build] --check: lib/ not written')
76
+ process.exit(0)
77
+ }
78
+ fs.mkdirSync(libDir, { recursive: true })
79
+
80
+ const info = {
81
+ package: 'dsh-memory-local',
82
+ builtAt: new Date().toISOString(),
83
+ node: process.version,
84
+ forkBase: {
85
+ upstream: `${forkBase.upstream.name}@${forkBase.upstream.version}`,
86
+ sha256: forkBase.source.sha256,
87
+ lines: forkBase.source.lines,
88
+ },
89
+ artifacts: [],
90
+ }
91
+ for (const a of artifacts) {
92
+ const buf = fs.readFileSync(a.from)
93
+ const srcSha = sha256(buf)
94
+ let wrote = 'written'
95
+ if (fs.existsSync(a.to) && sha256(fs.readFileSync(a.to)) === srcSha) wrote = 'unchanged'
96
+ else fs.writeFileSync(a.to, buf)
97
+ info.artifacts.push({ file: rel(a.to), src: rel(a.from), bytes: buf.length, sha256: srcSha, state: wrote })
98
+ console.log(`[build] ${wrote.padEnd(9)} ${rel(a.to)} ${buf.length} bytes ${srcSha.slice(0, 16)}`)
99
+ }
100
+ fs.writeFileSync(path.join(libDir, '.build-info.json'), `${JSON.stringify(info, null, 2)}\n`, 'utf8')
101
+ console.log(`[build] ok — base ${info.forkBase.upstream} sha256=${info.forkBase.sha256.slice(0, 16)}…`)
@@ -0,0 +1,20 @@
1
+ # The dsh-memory bundle patch: one row inserted over whatever layers came
2
+ # before it. A patch replaces the targeted row's whole `config`, so a profile
3
+ # overriding this row must restate every key it wants to keep.
4
+ #
5
+ # `path` has no code-side default on purpose — a durable store of user facts
6
+ # must not land in whatever directory the harness happened to start in. The
7
+ # deployment value lives here, beside the row, resolved through the loader's
8
+ # `dshHomePath` so every profile on this machine shares one memory file.
9
+
10
+ - insert:
11
+ - id: memory
12
+ name: dsh-memory
13
+ config:
14
+ path: !!js dshHomePath('memory/memory.db')
15
+ promptRecentCount: 10
16
+ promptMaxChars: 2000
17
+ maxTextChars: 2000
18
+ searchLimitDefault: 10
19
+ searchLimitMax: 50
20
+ promptOrder: 50