solopup-memory 0.21.0-beta.3 → 0.22.0-beta.3
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 +30 -0
- package/COMPATIBILITY.md +8 -5
- package/DETECTION.md +139 -0
- package/DREAMING-DESIGN.md +167 -0
- package/README.en.md +33 -6
- package/README.md +38 -7
- package/RELEASE.md +26 -0
- package/SECURITY.md +7 -0
- package/context-history.mjs +20 -3
- package/detect.mjs +441 -0
- package/eval/bench-detect.mjs +107 -0
- package/eval/semantic/cases.json +387 -0
- package/eval/semantic-suite.mjs +156 -0
- package/index.mjs +82 -10
- package/managed-policy.mjs +3 -1
- package/package.json +90 -69
- package/scripts/demo-source-recall.mjs +123 -0
- package/scripts/detect.mjs +69 -0
- package/scripts/dream.mjs +205 -0
- package/scripts/probe-history.mjs +92 -0
- package/scripts/probe-load.mjs +1 -1
- package/scripts/probe-package.mjs +6 -2
- package/scripts/security-check.mjs +173 -0
- package/scripts/soak.mjs +219 -0
- package/scripts/telemetry.mjs +187 -0
- package/scripts/verify.mjs +3 -1
- package/{test-adversarial.mjs → test/test-adversarial.mjs} +5 -5
- package/{test-belief-revision.mjs → test/test-belief-revision.mjs} +7 -7
- package/{test-candidates.mjs → test/test-candidates.mjs} +4 -4
- package/{test-capture-diagnostics.mjs → test/test-capture-diagnostics.mjs} +6 -6
- package/{test-capture-field-lineage.mjs → test/test-capture-field-lineage.mjs} +4 -4
- package/{test-capture-inputs.mjs → test/test-capture-inputs.mjs} +8 -8
- package/{test-capture-jobs.mjs → test/test-capture-jobs.mjs} +5 -5
- package/{test-capture-projections.mjs → test/test-capture-projections.mjs} +12 -12
- package/{test-capture-revision.mjs → test/test-capture-revision.mjs} +6 -6
- package/{test-capture-submission.mjs → test/test-capture-submission.mjs} +3 -3
- package/{test-capture-validation-flow.mjs → test/test-capture-validation-flow.mjs} +5 -5
- package/{test-capture-validation-job.mjs → test/test-capture-validation-job.mjs} +5 -5
- package/{test-capture-validation-lineage.mjs → test/test-capture-validation-lineage.mjs} +2 -2
- package/{test-capture-validation.mjs → test/test-capture-validation.mjs} +2 -2
- package/{test-capture.mjs → test/test-capture.mjs} +20 -20
- package/{test-compaction-compat.mjs → test/test-compaction-compat.mjs} +5 -5
- package/{test-compat.mjs → test/test-compat.mjs} +3 -3
- package/{test-concurrency.mjs → test/test-concurrency.mjs} +3 -3
- package/{test-conflict.mjs → test/test-conflict.mjs} +2 -2
- package/{test-context-history.mjs → test/test-context-history.mjs} +1 -1
- package/{test-control-schema.mjs → test/test-control-schema.mjs} +1 -1
- package/test/test-detect.mjs +125 -0
- package/test/test-dream-plan.mjs +72 -0
- package/test/test-dsh-registration.mjs +111 -0
- package/{test-episodes.mjs → test/test-episodes.mjs} +5 -5
- package/{test-explicit-memory.mjs → test/test-explicit-memory.mjs} +4 -4
- package/{test-field-lineage.mjs → test/test-field-lineage.mjs} +4 -4
- package/{test-history.mjs → test/test-history.mjs} +4 -4
- package/{test-inline-summary.mjs → test/test-inline-summary.mjs} +5 -5
- package/{test-legacy-source-identity.mjs → test/test-legacy-source-identity.mjs} +2 -2
- package/{test-links.mjs → test/test-links.mjs} +4 -4
- package/{test-managed-access.mjs → test/test-managed-access.mjs} +29 -5
- package/{test-managed-activation.mjs → test/test-managed-activation.mjs} +5 -5
- package/{test-meaning.mjs → test/test-meaning.mjs} +6 -6
- package/{test-native-service-lifecycle.mjs → test/test-native-service-lifecycle.mjs} +1 -1
- package/{test-native-write-validation.mjs → test/test-native-write-validation.mjs} +4 -4
- package/{test-packaging.mjs → test/test-packaging.mjs} +32 -5
- package/{test-paired-analysis.mjs → test/test-paired-analysis.mjs} +1 -1
- package/{test-patch.mjs → test/test-patch.mjs} +11 -11
- package/{test-plugin-contract.mjs → test/test-plugin-contract.mjs} +4 -4
- package/{test-privacy.mjs → test/test-privacy.mjs} +3 -3
- package/{test-project-stores.mjs → test/test-project-stores.mjs} +5 -5
- package/{test-publication.mjs → test/test-publication.mjs} +4 -4
- package/{test-restore.mjs → test/test-restore.mjs} +11 -11
- package/{test-retrieval.mjs → test/test-retrieval.mjs} +2 -2
- package/{test-revision-admission.mjs → test/test-revision-admission.mjs} +3 -3
- package/{test-rule-admission.mjs → test/test-rule-admission.mjs} +8 -8
- package/{test-runtime-startup.mjs → test/test-runtime-startup.mjs} +2 -2
- package/{test-schema.mjs → test/test-schema.mjs} +2 -2
- package/{test-security.mjs → test/test-security.mjs} +6 -6
- package/test/test-semantic-suite.mjs +20 -0
- package/{test-service-readiness.mjs → test/test-service-readiness.mjs} +1 -1
- package/{test-smell.mjs → test/test-smell.mjs} +4 -4
- package/{test-snapshots.mjs → test/test-snapshots.mjs} +3 -3
- package/{test-source-completeness.mjs → test/test-source-completeness.mjs} +6 -6
- package/{test-source-key.mjs → test/test-source-key.mjs} +2 -2
- package/{test-source-retirement.mjs → test/test-source-retirement.mjs} +4 -4
- package/{test-status-both.mjs → test/test-status-both.mjs} +12 -4
- package/{test-supersede.mjs → test/test-supersede.mjs} +3 -3
- package/test/test-telemetry.mjs +60 -0
- package/{test-text-admission.mjs → test/test-text-admission.mjs} +6 -6
- package/{test-tool-inputs.mjs → test/test-tool-inputs.mjs} +1 -1
- package/{test-tool-observations.mjs → test/test-tool-observations.mjs} +6 -6
- package/{test-tool-write-guard.mjs → test/test-tool-write-guard.mjs} +3 -3
- package/{test-tool-write-lifecycle.mjs → test/test-tool-write-lifecycle.mjs} +3 -3
- package/{test-usability.mjs → test/test-usability.mjs} +7 -7
- package/{test-validation-source-refs.mjs → test/test-validation-source-refs.mjs} +2 -2
- package/{test-validation-transition-context.mjs → test/test-validation-transition-context.mjs} +1 -1
- package/{test-withdrawal-archives.mjs → test/test-withdrawal-archives.mjs} +6 -6
- package/{test-withdrawal.mjs → test/test-withdrawal.mjs} +2 -2
- package/{test.mjs → test/test.mjs} +4 -4
- package/version.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.22.0-beta.3 — DSH 0.2.2 compatibility and first-run integration
|
|
4
|
+
|
|
5
|
+
- Await callable asynchronous Session Projection registrations before publishing tools, prompt contributions or the successful load marker. Retain the new handle and use its `stateOf(session)`; preserve the legacy registry reader for older hosts. Registration rejection fails activation.
|
|
6
|
+
- Integrate PR #2 first-run instructions, source-recall example and test-directory organization with the current detection, telemetry, dream planner and lock-contention fixes. All tests, including the newer main-branch suites, remain in the package and npm test.
|
|
7
|
+
- Add real CLI/Loader history-contract probes covering activation, live Session projection, scoped history replacement, cold replay, registration rejection and disposal, using isolated homes and synthetic input without model calls. The actual archive runs these checks too.
|
|
8
|
+
- This is a new source candidate, not a claim of npm publication, desktop semantic acceptance or production-data testing. Existing beta tags are unchanged.
|
|
9
|
+
|
|
10
|
+
## 0.22.0-beta.2 — detection layer, semantic pipeline gate, dream P0/P1
|
|
11
|
+
|
|
12
|
+
- Add `detect.mjs` and `scripts/detect.mjs`: read-only L0 invariant checks over a store or the whole memory root (index format, projection consistency, anchors, withdrawal residue, duplicates/conflicts, budgets, scope, version drift, topic structure, duplicate stores). No model calls, no writes.
|
|
13
|
+
- Expose a bounded `lint: { errors, warnings, checks[] }` summary in `memory_status` (single and scope=both); full details stay in the CLI.
|
|
14
|
+
- Record `capture/skipped/short-session-below-threshold` when a session ends below the auto-capture turn threshold, so short sessions are observable instead of silently losing context.
|
|
15
|
+
- Fix two stale comments that described the similarity gate as 0.95/0.85 while the constants are 0.90/0.80.
|
|
16
|
+
- Add `scripts/telemetry.mjs`: L3 read-only metrics (capture success rate, zero-output days, stale pending candidates, short-session skips) with `--json`/`--check`.
|
|
17
|
+
- Add `eval/semantic-suite.mjs` + `eval/semantic/cases.json`: 10 frozen L2 pipeline-fidelity cases (identity claim, conditional preference, project decision, inferred pending, verbatim-quote gate, scope gate, missing basis, supersede, condition-in-detail, expiry). Deterministic (~250ms); `semanticTruthEvaluated` stays false because it does not run a real extraction model.
|
|
18
|
+
- Add `eval/bench-detect.mjs`: comparison experiment against the 2026-11-08 manual audit baseline (detector recall, declared blind spots) plus median latency of L0/L3 gates.
|
|
19
|
+
- Tighten I14: mid-file paragraphs ending with unfinished punctuation are flagged; colon lead-ins followed by a list are not.
|
|
20
|
+
- Add `scripts/dream.mjs`: read-only P0 shadow planner (detection + telemetry → auditable ops, `applySupported:false`, zero model calls).
|
|
21
|
+
- Add `scripts/security-check.mjs`: mechanical pre-release checks (zero dependencies/install hooks, runtime network/exec surface, shipped-file secrets and absolute paths, workflow action pins and permissions, package contents, license, engines, gitignore). Integrated into `scripts/verify.mjs`.
|
|
22
|
+
- Fix the npm publish invocation: pass `./release/<tarball>` so npm 11 does not parse the relative path as a GitHub shorthand (previous `v0.22.0-beta.1` tag failed before any submission; no npm version was published).
|
|
23
|
+
- Add `scripts/soak.mjs`: reliability test on the official offline install path — repeated real DSH host start/stop, SIGKILL recovery, two concurrent hosts on one store, data fingerprint stability and store permissions (0700/0600).
|
|
24
|
+
- Add DETECTION.md (six-layer framework and its known blind spots) and DREAMING-DESIGN.md (next feature design; P0 implemented, P1+ not).
|
|
25
|
+
|
|
26
|
+
## 0.21.0-beta.4 - automated release infrastructure
|
|
27
|
+
|
|
28
|
+
- Add a repository-scoped GitHub Actions workflow for npm trusted publishing via OIDC, with beta tag/version checks and a fixed source commit.
|
|
29
|
+
- Test source on Linux/macOS and the actual archive; retain platform gate receipts, report shared-runner absolute timing misses, and require a fixed-beta.3 same-runner performance comparison. The original local Mac timing gate is unchanged.
|
|
30
|
+
- Verify the public npm download before creating the GitHub prerelease and updating the configured market index. No stored npm write token is required.
|
|
31
|
+
- No change to memory admission, retrieval, privacy classification, storage format or historical-erasure behavior. Actual hosted workflow/trust validation is recorded in release receipts, not assumed from this configuration.
|
|
32
|
+
|
|
3
33
|
## 0.21.0-beta.3 - private-memory exposure reduction
|
|
4
34
|
|
|
5
35
|
- Exclude recognized personal profiles, birth details, health, intimate and private contact information from automatic index projection and unrelated capture/review context, including private source quotations.
|
package/COMPATIBILITY.md
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
| 组件 | 版本 | 说明 |
|
|
19
19
|
|---|---|---|
|
|
20
|
-
| DeepSeek Harness
|
|
20
|
+
| DeepSeek Harness(桌面,历史验收) | **0.2.1-rc.3** | 既有桌面记录;不是本候选的新桌面验收 |
|
|
21
|
+
| DeepSeek Harness(Linux 隔离 CLI) | **0.2.1-rc.5、0.2.2-rc.1** | 官方 npm 分发;真实 Loader、Session 与投影生命周期,合成输入、零模型调用 |
|
|
21
22
|
| Node | 24.21.0 | 宿主内置;本机另装 v25.8.1 用于跑测试 |
|
|
22
23
|
| `engines.dsh` | `>=0.2.1-rc.0 <0.3.0` | package.json 声明;0.3 需要重新验证 |
|
|
23
24
|
|
|
@@ -29,7 +30,7 @@
|
|
|
29
30
|
| context 的 `text(context)` **同步**调用 | 返回字符串;异步会拿到 Promise 对象 | `resolveContext()` 直接调用 `entry.text(context)` |
|
|
30
31
|
| `context` 参数含 `{ agent, scope, signal }` | 从中取 `context.agent.session` | `dsh-agent/lib/types/dispatch.js` 的 `assembleContextFor` |
|
|
31
32
|
| **每步会再调 `refreshContext()`** | 它会按 provider 重新解析每条 context,覆盖装配钩子里的改写 | `dsh-agent-loop/lib/index.js` 调用点;`dsh-system-prompt` 的 `refreshContext` |
|
|
32
|
-
| `sessionProjections.register
|
|
33
|
+
| `await sessionProjections.register()` → `handle.stateOf(session)` | 等注册成功后才发布上下文、工具和成功标记;新宿主持有句柄;旧式返回值保留 registry `stateOf` 回退 | [0.2.2-rc.1 升级契约](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.2.2-rc.1/docs/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.md);两个官方 CLI 的真实加载、读取、冷重放、拒绝和释放测试 |
|
|
33
34
|
| `session.append(..., {surfaceOp:{op:'replace',startSeq:seq,endSeq:seq},sourceEventSeqs:[seq]})` | 只替换旧运行时快照,替换消息须含`role:'user'`;过滤命名记忆节并保留其他来源,原始事件不删除 | 当前`dsh-session`协议及实际宿主请求探针 |
|
|
34
35
|
| `ctx.workingDirectory.get(session)` | 同步返回绝对路径 | `dsh-working-directory/lib/index.js` |
|
|
35
36
|
| `sessionQuery.observeSession(id,{projectionMode:"none"})` | 经异步读平面取得只读事件观察,用后释放`Symbol.dispose`,结合活动surface及`isOwnSeq`核对来源;缺服务无持久恢复保证 | 当前`dsh-session-query`观察租约实现;不新增调用已弃用同步原始事件读接口 |
|
|
@@ -54,7 +55,7 @@ schema.properties.byType.additionalProperties must be a boolean
|
|
|
54
55
|
3. `required` 里的字段必须出现在 `properties`
|
|
55
56
|
4. 本机输出schema不接受`maxItems`、`maxLength`、`pattern`等额外约束关键字;dev.12原生加载曾因此明确失败,原日志保留。认识层schema使用已支持子集,数量、长度、维度与凭据检查由插件的实际输入校验器执行。
|
|
56
57
|
|
|
57
|
-
`test-schema.mjs` 把这三条搬进测试;`scripts/probe-load.mjs` 用隔离实例验证真加载。
|
|
58
|
+
`test/test-schema.mjs` 把这三条搬进测试;`scripts/probe-load.mjs` 用隔离实例验证真加载。
|
|
58
59
|
|
|
59
60
|
## 3. 运行时自检与降级
|
|
60
61
|
|
|
@@ -82,6 +83,8 @@ npm run gate
|
|
|
82
83
|
|
|
83
84
|
# 4. 真实加载:用一个隔离实例加载插件(不碰用户 profile)
|
|
84
85
|
node scripts/probe-load.mjs
|
|
86
|
+
# 真实 Session / Projection 注册和历史契约(合成输入、无模型调用):
|
|
87
|
+
node scripts/probe-history.mjs
|
|
85
88
|
# 更严格的离线打包、全新 home 验证:node scripts/probe-package.mjs
|
|
86
89
|
# 成功标志:隔离目录的 .loaded.json 版本与六工具注册匹配
|
|
87
90
|
|
|
@@ -139,7 +142,7 @@ DSH 自带对话压缩,桌面 profile 里启用的是这四个(`dsh-base/cor
|
|
|
139
142
|
|
|
140
143
|
| 接触面 | 会不会冲突 | 处理 |
|
|
141
144
|
|---|---|---|
|
|
142
|
-
| 运行时快照与压缩 | 快照会进入会话历史,可能被压缩;不能从provider重复渲染测试推断相反结论 | v0.11.0从当前库重建,按来源替换旧记忆节;既有普通摘要中的复述仍未清除。`test-compaction-compat.mjs`只验证provider和工具机制,实际请求另测 |
|
|
145
|
+
| 运行时快照与压缩 | 快照会进入会话历史,可能被压缩;不能从provider重复渲染测试推断相反结论 | v0.11.0从当前库重建,按来源替换旧记忆节;既有普通摘要中的复述仍未清除。`test/test-compaction-compat.mjs`只验证provider和工具机制,实际请求另测 |
|
|
143
146
|
| 注入体积 | **压缩救不了它**,它是每步都要付的固定税 | 索引硬上限 300 行 / 25 KB(`LIMITS`);测试断言 1000 条时注入仍 < 27 KB |
|
|
144
147
|
| 工具输出被修剪 | **会**——超过 8192 字符会在中间被截断,JSON 形状破坏 | search 输出 ≤4 KB;links 的入边/出边各截到 10 条并报总数;status < 2 KB |
|
|
145
148
|
| 压缩后模型忘记自己写过 | **会**导致重复写入 | 写入侧幂等(逐字重复 → `duplicate`)、相似度闸、冲突提示 |
|
|
@@ -147,7 +150,7 @@ DSH 自带对话压缩,桌面 profile 里启用的是这四个(`dsh-base/cor
|
|
|
147
150
|
### 命名
|
|
148
151
|
|
|
149
152
|
工具叫 `memory_prune` 而不是 `memory_compact`,避免与宿主 `/compact`(对话压缩)混淆。
|
|
150
|
-
`test-compaction-compat.mjs` 里有一条断言守着这个命名。
|
|
153
|
+
`test/test-compaction-compat.mjs` 里有一条断言守着这个命名。
|
|
151
154
|
|
|
152
155
|
### 结论
|
|
153
156
|
|
package/DETECTION.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# 记忆层检测框架(DETECTION)
|
|
2
|
+
|
|
3
|
+
> 目标不是“证明记忆层没问题”,而是**让每一类已经发生过的失败都有一个可复现的检测器**,
|
|
4
|
+
> 并把“没检测到”与“没问题”严格分开。检测器只读,不改记忆数据,不调用模型。
|
|
5
|
+
|
|
6
|
+
## 0. 结论先行
|
|
7
|
+
|
|
8
|
+
- **L0 不变量层已建成**:`detect.mjs` + `scripts/detect.mjs`,覆盖索引格式、投影一致性、锚点、
|
|
9
|
+
撤回传播、重复/冲突、预算、作用域、版本漂移、主题结构、跨库重复;已接入 `memory_status` 的 `lint` 摘要。
|
|
10
|
+
- **L1 管道行为层已经存在**:`npm test` 的 980 项确定性测试 + `eval/run-eval.mjs` 的逃逸/气味/写入/召回/fuzz。
|
|
11
|
+
- **L2 已有“管道保真层”**:`eval/semantic-suite.mjs` + 10 条冻结用例(确定性、243ms),验证“给定正确/错误候选,管道会不会弄丢或放宽”;**真模型抽取层仍缺**,`semanticTruthEvaluated=false`。
|
|
12
|
+
- **L3 长期观测层已建成**:`scripts/telemetry.mjs` 从账本算出捕获成功率、零产出天数、待审年龄、短会话跳过次数。
|
|
13
|
+
- 因此按本文第 3 节的判据,框架**还不算完备**;但它已经完备到可以给 L0 改动做门禁,
|
|
14
|
+
并明确指出下一步必须补 L2。
|
|
15
|
+
|
|
16
|
+
## 1. 分层与职责
|
|
17
|
+
|
|
18
|
+
| 层 | 回答的问题 | 机制 | 状态 |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| L0 不变量 | 库自身是否自洽(索引=账本投影、无悬空、无残留、不超预算) | `detect.mjs` | ✅ 已实现 |
|
|
21
|
+
| L1 管道行为 | 给定输入,写入/审查/撤回/注入的行为是否按契约 | `npm test`(980 项)、`eval/run-eval.mjs` | ✅ 已有 |
|
|
22
|
+
| L2 真实语义 | 真模型抽取后,记忆是否**记对**(精确率、条件保留、极性、归属、冷启动召回) | 管道保真层(确定性)+ 冻结留出集 + 真模型运行 | ◐ 管道层已建,真模型层缺 |
|
|
23
|
+
| L3 长期观测 | 在日常使用中,管道是否在产出、失败率、待审年龄、零产出天数 | `scripts/telemetry.mjs` | ✅ 已实现 |
|
|
24
|
+
| L4 安全与隐私 | 注入逃逸、指令气味、隐私覆盖、撤回残留 | `eval/run-eval.mjs` + `privacy.mjs` + 生成式对抗集 | ◐ 部分 |
|
|
25
|
+
| L5 性能与容量 | 渲染耗时、检索 p50/p95、字节预算随规模 | `eval/run-eval.mjs` 的 recall 扫描 | ✅ 已有 |
|
|
26
|
+
|
|
27
|
+
## 2. L0 检查项(已实现)
|
|
28
|
+
|
|
29
|
+
严重度约定:`error` = 库已不可信或即将丢数据;`warning` = 会误导人或迟早出错;`info` = 需要知道但不阻断。
|
|
30
|
+
|
|
31
|
+
| ID | 检查 | 严重度 |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| I0 | 候选账本不可读 / 检测器异常 | error |
|
|
34
|
+
| I1 | 索引行类型非法、摘要超 200 字、期限语法错误 | error / warning |
|
|
35
|
+
| I2 | 索引指向的主题文件不存在、锚点在标题里找不到 | error / warning |
|
|
36
|
+
| I3 | 有效记录未投影到索引、正文块与账本不一致、正文文件缺失 | error |
|
|
37
|
+
| I4 | 索引行没有账本依据(手工/旧格式),只提示不删除 | info |
|
|
38
|
+
| I5 | 撤回后索引仍残留旧内容、撤回策略不可读 | error / warning |
|
|
39
|
+
| I6 | 完全重复行、相似度 ≥ 0.9 的近重复 | warning |
|
|
40
|
+
| I7 | `conflictSignature` 相同但取值不同(同属性并存) | warning |
|
|
41
|
+
| I8 | 索引行数/字节超限、库占用超限 | error |
|
|
42
|
+
| I9 | 记录作用域与库作用域不符 | error |
|
|
43
|
+
| I10 | 索引提到与当前 `VERSION` 不同的版本号(只能提示,不自动判定谁对) | info |
|
|
44
|
+
| I11 | 隐私记录只在按需检索返回,但明文仍在主题文件与账本 | info |
|
|
45
|
+
| I12 | 有索引但没有历史账本,无法回答“当时怎么记的” | info |
|
|
46
|
+
| I13 | 正文块在账本里不存在、或对应记录已非有效状态 | warning |
|
|
47
|
+
| I14 | 正文块出现在标题之前、主题文件末行像被截断 | warning |
|
|
48
|
+
| I15 | 主题标题没有索引指向(仅在该文件已使用锚点引用时检查) | info |
|
|
49
|
+
| X1 | 空项目库 | info |
|
|
50
|
+
| X2 | 内容完全相同的库(重复库/遗留副本) | warning |
|
|
51
|
+
| X3 | 项目库数量与空库数量 | info |
|
|
52
|
+
|
|
53
|
+
实现位置:[detect.mjs](detect.mjs)(`detectStore` / `detectRoot`)。
|
|
54
|
+
测试:[test-detect.mjs](test-detect.mjs)(5 项,覆盖格式、投影、冲突、预算、跨库重复)。
|
|
55
|
+
|
|
56
|
+
## 3. 完备性判据
|
|
57
|
+
|
|
58
|
+
一个检测框架算“完备”,当且仅当:**对每一类已经观察到的失败,都存在一个可复现的最小 fixture
|
|
59
|
+
和一个非零退出码的门禁**。按这个判据逐项核对:
|
|
60
|
+
|
|
61
|
+
| 已观察到的失败 | L0 | L1 | L2 |
|
|
62
|
+
|---|---|---|---|
|
|
63
|
+
| 索引悬空、正文缺失、索引/正文不一致 | ✅ I2/I3/I13 | ✅ | — |
|
|
64
|
+
| “5/5”与“6/6”这类**同一事实不同数字** | ❌ 签名不同,抓不到 | — | ◐ 需语义对 |
|
|
65
|
+
| 记忆里写死的版本号过时 | ◐ I10 只提示 | — | ◐ |
|
|
66
|
+
| 一次性指令被记成长期决定 | — | ◐ 有反例测试 | ❌ 缺留出集 |
|
|
67
|
+
| 抽取引用用户原话失败(invalid-user-evidence) | — | ✅ 拒写 | ❌ 缺精确率 |
|
|
68
|
+
| 短会话永不触发捕获 | — | — | ❌ 缺遥测 |
|
|
69
|
+
| 待审候选永久挂起 | ◐ 只在 metric 里计数 | — | ❌ |
|
|
70
|
+
| 条件/归属/过期在写入后是否还正确 | — | — | ✅ 10 条 `semantic-suite` 用例 |
|
|
71
|
+
| 注入逃逸 | — | ✅ `run-eval` 逃逸率 | ◐ 泛化差(留出集 TPR 20%) |
|
|
72
|
+
| 隐私降载只到索引层 | ◐ I11 | ✅ 规则测试 | ❌ 缺覆盖度量 |
|
|
73
|
+
|
|
74
|
+
**结论**:L0 对“投影自洽”这一类是完备的;对“语义正确”“长期是否在产出”“隐私是否真隔离”不完备。
|
|
75
|
+
所以框架目前是**可用的门禁**,不是**完整的验收**。下一步优先级见第 6 节。
|
|
76
|
+
|
|
77
|
+
## 4. 怎么跑
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
node scripts/detect.mjs # L0 不变量,人类可读
|
|
81
|
+
node scripts/telemetry.mjs # L3 长期观测(捕获成功率/零产出天数/待审年龄)
|
|
82
|
+
node eval/semantic-suite.mjs # L2 管道保真层(10 条冻结用例)
|
|
83
|
+
node eval/bench-detect.mjs # 对比实验:检测器召回 vs 人工审计 + 各环节耗时
|
|
84
|
+
node scripts/detect.mjs --verbose # 带修复提示与 info
|
|
85
|
+
node scripts/detect.mjs --json # 机器可读(含 metrics)
|
|
86
|
+
node scripts/detect.mjs --check # 有 error 时退出码 1(CI 门禁)
|
|
87
|
+
npm run detect # 同上,走 package.json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
在宿主里也可以直接看摘要:`memory_status` 的返回新增 `lint: { errors, warnings, checks[] }`,
|
|
91
|
+
文本渲染会加一行“检测(L0):error N、warning N;检查项×次数”。
|
|
92
|
+
|
|
93
|
+
建议门禁:
|
|
94
|
+
- 每次改 `index.mjs`/`writeMemory`/`prune`:`node --test test-detect.mjs` + `npm test`。
|
|
95
|
+
- 发布前:`node scripts/detect.mjs --check` 对真实库跑一次(只读,不阻止发布但要求解释每个 error)。
|
|
96
|
+
- 每周:`--verbose` 人工过一遍 info,决定哪些该 supersedes。
|
|
97
|
+
|
|
98
|
+
## 5. 已知盲区(必须写进报告,不能默认没有)
|
|
99
|
+
|
|
100
|
+
1. **语义真值不可自动获得**:L0 只能证明“库自洽”,不能证明“库说得对”。同一事实的两种措辞、
|
|
101
|
+
数字矛盾、时态/极性错误,L0 抓不到;“两个数字都活着”这种现象要靠 L2 或人工。
|
|
102
|
+
2. **记忆与现实的漂移**(版本号、外部事实变化)只能弱提示,不能自动判定。
|
|
103
|
+
3. **隐私是暴露面报告**:检测器能数出明文在哪里,但不会、也不该自动删用户数据。
|
|
104
|
+
4. **多进程/多宿主并发**:L0 读的是某一时刻快照,不构成并发安全证明。
|
|
105
|
+
5. **跨库语义重复**:只做字节级(X2),不做“两个项目库说了同一件事”的语义比对。
|
|
106
|
+
6. **检测器自身失效**:`lint-unavailable` 会作为 warning 出现;但动态导入失败只能降级,不能替代真实检查。
|
|
107
|
+
|
|
108
|
+
## 6. 下一步(按价值排序)
|
|
109
|
+
|
|
110
|
+
1. **L2 真模型层**(最高优先):现有 10 条管线用例只证明“管道不弄丢”;还需要在真实宿主里录一次
|
|
111
|
+
真模型抽取并冻结回放,才能测“模型抽得对不对”。在补上它之前,任何“写入质量提升”都只算半验证。
|
|
112
|
+
2. **L3 使用计数**:记录哪条记忆被检索/被引用(现在只有“有没有产出”,没有“哪条有用”);
|
|
113
|
+
这是热点集与衰减策略的输入。
|
|
114
|
+
3. **L4 生成式对抗集**:每轮重新生成注入样本,避免规则拟合(现有留出集 TPR 20% 就是教训)。
|
|
115
|
+
4. **L0 扩展**:把“主题文件末行截断”“正文块无标题”升级为可修复建议;把 `I7` 扩展到跨库。
|
|
116
|
+
|
|
117
|
+
## 6.1 对比实验(2026-11-08)
|
|
118
|
+
|
|
119
|
+
以人工只读审计为基线(见 `eval/bench-detect.mjs` 的 `BASELINE`):
|
|
120
|
+
|
|
121
|
+
| 指标 | 结果 |
|
|
122
|
+
|---|---|
|
|
123
|
+
| L0 召回(只算“应由 L0 抓”的 6 项) | 6/6 = 100% |
|
|
124
|
+
| 已声明盲区(不冒充覆盖) | 同事实数字矛盾(5/5 vs 6/6)、规则阈值冲突(100 行 vs 200 行) |
|
|
125
|
+
| 其他层归属 | 待审年龄 → L3;状态字段缺失 → 文档一致性;空库重复 → 设计允许(不报噪音);索引摘要无正文 → 设计允许 |
|
|
126
|
+
| L0 耗时(真实库 9 个 store,20 次) | 中位 35.2ms,范围 28.5–50.0ms |
|
|
127
|
+
| L3 耗时(20 次) | 中位 13.7ms |
|
|
128
|
+
| 规模对照(单 store) | 300 行索引 63.3ms;1000 行 115.2ms(相似度对上限 400) |
|
|
129
|
+
| L2 管道套件 | 10 例 / 18 断言 / 约 190ms |
|
|
130
|
+
| 对照:完整 `npm test` | 约 77–85s |
|
|
131
|
+
|
|
132
|
+
结论:L0/L3 作为门禁比完整测试便宜约三个数量级,且能检查真实库(测试套件不能);
|
|
133
|
+
L2 管道层补的是“写入后条件/认识层/过期是否还在”的契约,不替代真模型语义验收。
|
|
134
|
+
|
|
135
|
+
## 7. 设计立场
|
|
136
|
+
|
|
137
|
+
- 检测器只读,修复永远是另一个显式动作(`prune`/`supersedes`/人工确认)。
|
|
138
|
+
- 不把“没有 findings”写成“没有问题”:每条 `[ok]` 都带“不等于语义质量”的提醒。
|
|
139
|
+
- 与项目既有反偏置传统一致:调参集、外部集、冻结留出集分开,冻结后只测一次。
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# 做梦(DREAMING)设计草案
|
|
2
|
+
|
|
3
|
+
> 下一功能:在夜间/低调用时段,由本地插件自己整理记忆。
|
|
4
|
+
> 本文先给外部事实(谁真的做了、证据多强),再给可落地的设计。
|
|
5
|
+
> **P0 影子报告 + P1 安全应用已实现**(`scripts/dream.mjs`):P1 只自动执行 `compact-index`(复用 `pruneStore`),要求 `--reviewed <planHash>`、先备份、应用后 L0 复核;其余 op 明确留给人工。
|
|
6
|
+
|
|
7
|
+
## 0. 结论先行
|
|
8
|
+
|
|
9
|
+
- **Anthropic 已经在 2026-11-06 公开了 “dreaming”**:四层记忆
|
|
10
|
+
transcripts → memory notes → wiki 表征 → 注入上下文,dreaming 在空闲期做三件事:
|
|
11
|
+
用 transcript 校对笔记、建/并 wiki、把笔记上提到注入层。
|
|
12
|
+
同机制已产品化为 Managed Agents 的 **Dreams API**:异步 job,输入 = 1 个已有 store + 1–100 个 session,
|
|
13
|
+
**输出新 store、输入永不修改**,可 cancel,失败保留部分产出。
|
|
14
|
+
- **OpenAI Codex 没有 “dreaming” 这个词**,但官方文档确认了后台整合的调度哲学:
|
|
15
|
+
等会话 idle 足够久、跳过活跃/短会话、剩余 rate-limit 低于阈值就跳过这一轮;
|
|
16
|
+
第三方源码分析(非官方)显示两阶段抽取/合并、owner token + lease、watermark、按 thread 差量遗忘。
|
|
17
|
+
- **Claude Code 本身不做睡眠整合**:auto memory 只在会话内写,MEMORY.md 只注入前 200 行/25KB。
|
|
18
|
+
- 对 SoloPup 的结论:**不要做“全库重写式做梦”**。应做“事件驱动 + 水位 + 三档输入 + shadow 库 diff
|
|
19
|
+
+ 人工确认”的小步整理;所有操作走 op 账本,天然可 diff、可撤回、可崩溃恢复。
|
|
20
|
+
这是 SoloPup 相对 Anthropic“整库克隆”的结构优势,代价是必须做 op 级幂等。
|
|
21
|
+
|
|
22
|
+
## 1. 外部事实(2026-11-08 访问)
|
|
23
|
+
|
|
24
|
+
| 来源 | 关键事实 | 证据强度 |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| Anthropic《The components of agent memory》(2026-11-06) | dreaming 定义为空闲期用 transcript 校对笔记、构建/合并 wiki、把笔记上提到注入层;四层结构 | 官方研究文 |
|
|
27
|
+
| Anthropic Dreams API(Managed Agents,research preview) | 异步 job;输入 store + sessions;**输出新 store,输入永不修改**;状态机 pending/running/completed/failed/canceled;`instructions` 只能做高层综合;按时长线性计费 | 官方文档 |
|
|
28
|
+
| Claude Code memory 文档 | auto memory 会话内联写;无睡眠整合;注入前 200 行/25KB | 官方文档 |
|
|
29
|
+
| Codex memories 文档 | 后台更新;等 idle;跳过活跃/短会话;rate-limit 低于阈值跳过 pass;可配 extract/consolidation 双模型 | 官方文档 |
|
|
30
|
+
| Codex 源码分析(第三方) | 两阶段抽取/合并、SQLite owner token + 1h lease + 90s 心跳、watermark、selection diff + usage_count、按 thread 差量遗忘;无向量 | 第三方,非官方 |
|
|
31
|
+
| Letta sleep-time compute(arXiv 2504.13171) | 离线预计算可预测查询;同等准确率测试算力降约 5×,准确率 +13%/+18%;强依赖查询可预测性 | 论文 |
|
|
32
|
+
| A-MEM(arXiv 2502.12110) | 原子笔记 + LLM 建链 + 记忆演化(新记忆改写旧笔记);风险是静默改写与幻觉建链 | 论文 |
|
|
33
|
+
| MemoryOS(arXiv 2506.06326) | 分层记忆 + 热度/时间驱动更新与淘汰 | 论文 |
|
|
34
|
+
| Generative Agents(arXiv 2304.03442) | memory stream + 反思:重要度累积过阈值生成高层反思写回 | 论文 |
|
|
35
|
+
| Google Sleep framework(博客) | 把“睡眠期”引入持续学习 | 官方博客,非论文 |
|
|
36
|
+
|
|
37
|
+
**注意**:Anthropic 和 OpenAI 都没有“夜间自动做梦”的官方调度文档;Dreams 由调用方触发。
|
|
38
|
+
“晚上自己做梦”是我们自己的调度设计,不是照抄。
|
|
39
|
+
|
|
40
|
+
## 2. Anthropic 公布的反面数据(最值得抄的部分)
|
|
41
|
+
|
|
42
|
+
这些数字比“能力宣称”有用,因为它们定义了失败模式:
|
|
43
|
+
|
|
44
|
+
| 现象 | 数据 |
|
|
45
|
+
|---|---|
|
|
46
|
+
| 记忆文件越多 ≠ 越好 | 宝可梦约 1 万步:9 个文件拿 4 徽章;413 个文件只拿 1 徽章 |
|
|
47
|
+
| 纠错有效 | 记错 PokéCenter 方位,dreaming 对照 transcript 改回后 1935 步抵达新城;未纠错版 3 次掉崖后放弃 |
|
|
48
|
+
| 规模收益 | 35 万文档、128 次 dreaming:25 题达标率 13% → 48%;wiki+search 54% → 61%,每问省约 2 万 token |
|
|
49
|
+
| 表征膨胀 | 一次 wiki 膨胀到语料 **1.77 倍**(抽象为零) |
|
|
50
|
+
| 并发覆写丢内容 | 多 agent 同写一页,57 条要点只剩 41 条(72%) |
|
|
51
|
+
| 官方自述 | “全量校验不划算,频率应按易变程度/访问频率调” |
|
|
52
|
+
|
|
53
|
+
三条直接约束:
|
|
54
|
+
1. **整理必须可验证**:每次 dream 的产出要和输入 diff,不能静默替换。
|
|
55
|
+
2. **禁止无证据改写**:每条 op 必须能指回原话 / 原记录 id,否则不写。
|
|
56
|
+
3. **频率按易变程度**:高频变动的条目多查,冷条目抽查;不是每晚全库。
|
|
57
|
+
|
|
58
|
+
## 3. SoloPup 做梦的定位
|
|
59
|
+
|
|
60
|
+
现有架构里,dream 是**第二个消费者**,不是新的事实来源:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
对话事件 → 自动捕获(抽取 + 审查)→ 候选账本 → 有效记忆 → 索引注入 / 检索
|
|
64
|
+
↘
|
|
65
|
+
dream(只读账本 + 索引 + 主题文件)
|
|
66
|
+
↘ op 计划 → shadow 目录 → diff → 人工确认 → 原子应用
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- 复用:`candidates.mjs`(候选状态机)、`episodes.mjs`(历史)、`withdrawal.mjs`(撤回)、
|
|
70
|
+
`detect.mjs`(L0 不变量)、`pruneStoreLocal`(确定性压缩)、`publication.mjs`(原子发布)。
|
|
71
|
+
- 不新增:向量库、图数据库、云服务、常驻定时器、第二个事实库。
|
|
72
|
+
|
|
73
|
+
## 4. 调度:事件驱动 + AND 门
|
|
74
|
+
|
|
75
|
+
不要 `setInterval` 常驻。在 `session/disposed`、`step/end` 或插件启动时做一次“是否该 dream”的判定,
|
|
76
|
+
满足全部条件才启动;启动后立刻写租约,防止多宿主同时做梦。
|
|
77
|
+
|
|
78
|
+
| 门 | 条件 | 理由 |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| G1 变更水位 | 自上次 dream 后新增 capture ≥ N(默认 10)或距上次 ≥ 12h | 没新东西不整理 |
|
|
81
|
+
| G2 静默 | 最近会话静默 ≥ 20min(本地时间戳) | 对应 Codex 的 idle |
|
|
82
|
+
| G3 待审压力 | pending 候选 ≤ K(默认 20) | 待审积压时先清积压,不做二次抽象 |
|
|
83
|
+
| G4 预算 | 当日 dream token 预算未用尽;最近一次模型调用失败率 < 阈值 | 对应 Codex 的 rate-limit 阈值 |
|
|
84
|
+
| G5 独占 | `node:sqlite` 全局锁 + owner token + 1h lease + 90s 心跳 | 多进程/多宿主 |
|
|
85
|
+
| G6 用户开关 | 配置 `dream.enabled` 默认 false;首次启用需人工确认 | 隐私与成本 |
|
|
86
|
+
|
|
87
|
+
失败与恢复:lease 过期视为 abandoned,保留部分产出供检查;未开始的工作可重领,已领取不重发
|
|
88
|
+
(沿用现有 `capture-jobs` 的语义)。**不做“夜间定时器”**,只做“事件到来时按水位判断”。
|
|
89
|
+
|
|
90
|
+
## 5. 输入:三档并集,全部封顶
|
|
91
|
+
|
|
92
|
+
| 档 | 内容 | 上限 |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| A 变更集 | watermark 之后的 capture、未审候选、冲突对(`I7` findings) | ≤ 50 条 |
|
|
95
|
+
| B 热点集 | 近 30 天被 `memory_search` 命中或被注入的条目 id(需先有 L3 使用计数) | ≤ 30 条 |
|
|
96
|
+
| C 冷抽查 | 随机抽样做陈旧/衰减检查 | ≤ 20 条 |
|
|
97
|
+
|
|
98
|
+
transcript 用已有会话日志,**不全库扫描**。输入本身只读;所有 op 必须带 evidence(原话引用、
|
|
99
|
+
recordId、或 detect finding id)。
|
|
100
|
+
|
|
101
|
+
## 6. 操作清单(按风险从低到高)
|
|
102
|
+
|
|
103
|
+
| # | 操作 | 确定性? | 安全闸 |
|
|
104
|
+
|---|---|---|---|
|
|
105
|
+
| D1 | 同键去重合并(`conflictSignature` 相同且仅一处取值不同) | 确定性 | 只归档不删除;保留双方 recordId |
|
|
106
|
+
| D2 | 索引压缩:>300 行/25KiB 时把细节移到主题文件、索引留摘要 | 确定性 | 先 shadow diff;可回滚 |
|
|
107
|
+
| D3 | 索引/正文对齐(I3/I13 修复) | 确定性 | 以账本为准重建正文块;不新写事实 |
|
|
108
|
+
| D4 | 撤回残留清理(I5) | 确定性 | 复用现有撤回发布路径 |
|
|
109
|
+
| D5 | 冲突仲裁:同一属性多个取值,留最新并写 `supersedes` | 需人工 | 必须显示两个取值与来源;默认不自动应用 |
|
|
110
|
+
| D6 | 衰减归档:长期未引用 + 过期 + 低重要度 → archive 区 | 确定性 + 人工 | 不删除;可恢复 |
|
|
111
|
+
| D7 | 建链:related / contradicts(不产新正文) | 确定性(相似度) | 只增边;可 `memory_links` 查 |
|
|
112
|
+
| D8 | 按 transcript 纠错(对照原话改摘要) | 需模型 | 必须列出原话引用;改注入层需人工确认 |
|
|
113
|
+
| D9 | 洞察(≥2 条既有记忆归纳) | 需模型 | 必须列引用 id;禁止无引用新事实;每日上限 |
|
|
114
|
+
|
|
115
|
+
**禁止**:整库重写、无证据改写、自动删除主题文件、自动改写用户手工条目(I4 类)。
|
|
116
|
+
|
|
117
|
+
## 7. Shadow 库 + diff + 人工确认
|
|
118
|
+
|
|
119
|
+
Anthropic 的 Dreams API 用“输出新 store、输入不变”换安全;SoloPup 用更细的 **op 计划**换可审计:
|
|
120
|
+
|
|
121
|
+
1. dream 只写 `<store>/.dream/<runId>/`(计划 JSON + 预览 Markdown),不碰正式库。
|
|
122
|
+
2. 每个 op 记录:`{opId, kind, target, beforeHash, afterHash, evidence[], risk}`。
|
|
123
|
+
3. `scripts/dream.mjs status|diff|apply`:
|
|
124
|
+
- `diff` 输出人类可读的 before/after 与证据;
|
|
125
|
+
- `apply` 需要 `--reviewed <planHash>`,逐 op 原子应用;每个 op 幂等(content hash + opId)。
|
|
126
|
+
4. 崩溃恢复:op 日志 + 发布锁;已应用 op 不重复,未应用可续。
|
|
127
|
+
5. 任何 op 失败不阻断主对话;失败进 `.audit.jsonl`,`memory_status` 可见。
|
|
128
|
+
|
|
129
|
+
## 8. 指标(dream 前/后对比)
|
|
130
|
+
|
|
131
|
+
| 指标 | 定义 | 门槛(建议) |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| 索引行数/字节 | 注入预算占用 | 不增长或下降 |
|
|
134
|
+
| 同键重复数 | I6/I7 计数 | 下降 |
|
|
135
|
+
| 未仲裁冲突数 | I7 | 下降 |
|
|
136
|
+
| 投影不一致数 | I3/I13 | = 0 |
|
|
137
|
+
| 撤回残留 | I5 | = 0 |
|
|
138
|
+
| 冷启动召回 | 冻结查询集(L2) | 不下降 |
|
|
139
|
+
| 新事实幻觉率 | 人工复核 op 中有无 evidence | = 0 |
|
|
140
|
+
| 每轮 op 数 / token / 时长 | 账本统计 | 有上限 |
|
|
141
|
+
|
|
142
|
+
评测方式:固定 20–30 条**真实历史查询**做 dream 前/后盲评(沿用项目现有盲评流程),不做线上 A/B;
|
|
143
|
+
golden set 加一条禁止项“不得出现无 evidence 的新事实”。
|
|
144
|
+
|
|
145
|
+
## 9. 分阶段落地
|
|
146
|
+
|
|
147
|
+
| 阶段 | 内容 | 验收 |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| P0 影子报告 | 只跑检测 + 生成 op 计划,不落盘(已实现:`node scripts/dream.mjs`) | `dream` 能解释每个 op 的证据,`--json` 可审计;`applySupported=false` |
|
|
150
|
+
| P1 确定性整理 | `compact-index` 自动 apply(`pruneStore`,带备份与 reviewed 哈希);其余 op 明确跳人工 | 临时库验证:超限索引回落、重复/过期移除、可重复执行、验证不恶化 |
|
|
151
|
+
| P2 冲突与衰减 | D5、D6 自动建议 | 冲突数下降;无“越整理越错”的人工复核 |
|
|
152
|
+
| P3 模型类操作 | D8、D9(默认关闭,人工确认) | 幻觉率为 0;成本在预算内 |
|
|
153
|
+
|
|
154
|
+
## 10. 与“做梦”相关的设计取舍
|
|
155
|
+
|
|
156
|
+
- **不抄整库克隆**:SoloPup 的账本已经比一次性重写更细;整库替换会丢掉撤回屏障与历史。
|
|
157
|
+
- **不抄“自动应用”**:Anthropic 的 API 让调用方拿新 store 自行决定;我们也必须让人看见 diff。
|
|
158
|
+
- **不抄“全量校验”**:官方自己说全量不划算;用易变度/访问频率决定查什么。
|
|
159
|
+
- **不引入第二事实源**:dream 的产出仍走 `writeMemory` 的同一套闸门(来源、审查、去重、配额)。
|
|
160
|
+
- **保留“什么都没做”**:没有值得整理的变更时,dream 必须能返回空并记录“跑过但无 op”。
|
|
161
|
+
|
|
162
|
+
## 11. 开放问题
|
|
163
|
+
|
|
164
|
+
1. L3 使用计数还没实现,B 档热点集暂时只能靠 `memory_search` 的审计日志反推。
|
|
165
|
+
2. 主题文件当前是自由 Markdown,D2 的“细节下移”需要先定义卡片块边界(`[candidate:id]` 已可用)。
|
|
166
|
+
3. 多宿主并发下,“静默 ≥20min”需要一个共享时钟来源;目前只能看本地 `capture-state.json` 时间戳。
|
|
167
|
+
4. dream 的模型调用是否复用自动捕获的 provider/model,还是允许单独配置(建议后者,便于限额)。
|
package/README.en.md
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
1
|
# SoloPup Memory
|
|
2
2
|
|
|
3
|
+
**Start here:** [Quick start](docs/guides/quickstart.md) · [Synthetic trials](docs/README.md) · [FAQ](docs/faq.md) · [Feedback](docs/feedback.md)
|
|
4
|
+
|
|
3
5
|
**Remember what matters. Keep up when you change your mind.** · [中文](README.md)
|
|
4
6
|
|
|
5
|
-
Source-linked, layered **text memory** for DeepSeek Harness. **
|
|
7
|
+
Source-linked, layered **text memory** for DeepSeek Harness. **Public beta, not a stable release.** See the npm beta tag and GitHub releases for the currently published version. See [RELEASE.md](RELEASE.md) for tested scope and known gaps.
|
|
8
|
+
|
|
9
|
+
## Quick install
|
|
10
|
+
|
|
11
|
+
Requires an installed DeepSeek Harness and Node >=24.9. For the desktop profile:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
dsh plugin --profile desktop add solopup-memory@beta --ignore-scripts
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Restart that profile's host, then use `memory_status` to check the loaded version and status. If upgrading from `dsh-memory`, back up and remove the old plugin first; do not enable both. See [installation details](#install-in-dsh) for exact versions, legacy-store review and removal.
|
|
18
|
+
|
|
19
|
+
## What does a source-linked result look like?
|
|
20
|
+
|
|
21
|
+
These are **actual offline script results from Linux x64 / Node v24.22.1 on 2026-11-07**. They use a fictional message and production tool handlers in a scripted host, with a stubbed approval response. Write, same-project recall and other-project recall run in three separate Node processes; neither reader inherits old messages. **This is not a real DSH conversation or a real-model semantic evaluation.**
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
synthetic user: 记住:本项目的交付说明统一用中文。
|
|
25
|
+
memory_write: recorded (scope=project, meaning=decision)
|
|
26
|
+
fresh process / memory_search("交付说明"): 1 hit (scope=project)
|
|
27
|
+
current text: - [project] 本项目的交付说明统一用中文 — 索引摘要
|
|
28
|
+
history source: synthetic-demo-write:1; quote: 记住:本项目的交付说明统一用中文。
|
|
29
|
+
other project / current + history: 0 + 0 hits
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The Chinese message asks to keep this project's delivery notes in Chinese. Current search returns its effective summary. A separate `memory_search({query: "交付说明", mode: "exact", view: "history"})` returns the original quote and message identity; historical content is not a current instruction. The six lines summarize tool results. See the [full receipt and limitations](docs/runs/2026-11-07-source-recall.md), or run `node scripts/demo-source-recall.mjs` from the checkout. [Natural fresh-chat acceptance](docs/guides/fresh-chat.md) still needs a separate DSH run.
|
|
33
|
+
|
|
34
|
+
## What it keeps
|
|
6
35
|
|
|
7
36
|
- Separate global preferences from project decisions.
|
|
8
37
|
- Keep original owner-message citations, conditions, exceptions and optional expiry.
|
|
@@ -13,11 +42,9 @@ Source-linked, layered **text memory** for DeepSeek Harness. **0.21.0-beta.3 is
|
|
|
13
42
|
|
|
14
43
|
## Install in DSH
|
|
15
44
|
|
|
16
|
-
|
|
17
|
-
dsh plugin --profile desktop add github:OakcoderX/solopup-memory#v0.21.0-beta.3 --ignore-scripts
|
|
18
|
-
```
|
|
45
|
+
Use the official plugin-manager command in [Quick install](#quick-install).
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
The beta tag follows verified public beta releases. For an exact version, choose a published version from the release page, for example `solopup-memory@0.21.0-beta.3`. Git installation remains available with `github:OakcoderX/solopup-memory#v0.21.0-beta.3`; the release page supplies a full commit SHA for an immutable Git pin. This package ships executable ESM and has no dependency installation or build scripts. Alternatively download its release tarball and install the local file with `dsh plugin --profile desktop add /absolute/path/to/solopup-memory-0.21.0-beta.3.tgz --offline --ignore-scripts`.
|
|
21
48
|
|
|
22
49
|
Restart the profile and use `memory_status`. Existing legacy stores may require explicit local review. Do not delete control files to bypass that review. If upgrading from `dsh-memory`, create a full private backup, stop the hosts using that data, remove the old package, then install SoloPup Memory. Do not run both packages together. The data location and legacy format identifiers are intentionally retained.
|
|
23
50
|
|
|
@@ -47,7 +74,7 @@ Verified locally on macOS with DSH Node 24. Other runtime/platform results must
|
|
|
47
74
|
|
|
48
75
|
## Development
|
|
49
76
|
|
|
50
|
-
Requires Node >=24.9. No npm dependencies are needed for the test suite.
|
|
77
|
+
Requires Node >=24.9. No npm dependencies are needed for the test suite. Tests live in `test/`; runtime modules retain their existing paths. The full explicit test set is preserved in both `npm test` and the package archive.
|
|
51
78
|
|
|
52
79
|
```sh
|
|
53
80
|
npm test
|
package/README.md
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
# SoloPup Memory
|
|
2
2
|
|
|
3
|
+
**新用户入口:** [快速上手](docs/guides/quickstart.md) · [六个虚构试用案例](docs/README.md) · [常见问题](docs/faq.md) · [反馈](docs/feedback.md)
|
|
4
|
+
|
|
3
5
|
**记住重要的事,跟上你的改变。** · [English](README.en.md)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
这是文字记忆公开测试版,尚未通过稳定版验收。当前发行版本以 [npm beta 标签](https://www.npmjs.com/package/solopup-memory) 与 [GitHub 发行页](https://github.com/OakcoderX/solopup-memory/releases) 为准。已验证范围和已知问题见 [RELEASE.md](RELEASE.md)。
|
|
6
8
|
|
|
7
9
|
把用户明确表达的长期偏好、项目决定、可查证线索和暂定信念保存下来,在后续对话中按项目与适用条件找回。首次公开版本只处理文字。
|
|
8
10
|
|
|
11
|
+
## 先试起来
|
|
12
|
+
|
|
13
|
+
需要已安装 DeepSeek Harness,Node >=24.9。以下以 desktop profile 为例:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
dsh plugin --profile desktop add solopup-memory@beta --ignore-scripts
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
重启该 profile 的宿主后,用 `memory_status` 确认插件版本与状态。升级旧名 `dsh-memory` 前先完整备份并移除旧插件,不能同时启用两个插件;固定版本、旧库检查和卸载见[安装与卸载](#安装与卸载)。
|
|
20
|
+
|
|
21
|
+
## 原话来源会怎样返回?
|
|
22
|
+
|
|
23
|
+
下面是 **2026-11-07 在 Linux x64 / Node v24.22.1 实际执行的离线示例输出**,使用虚构消息、生产工具处理函数和脚本化宿主;审查回复由测试桩固定通过。写入、同项目检索、另一项目检索分别在三个新 Node 进程中运行,后两者不继承旧消息。**这不是实际 DSH 聊天或真实模型的语义验收。**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
synthetic user: 记住:本项目的交付说明统一用中文。
|
|
27
|
+
memory_write: recorded (scope=project, meaning=decision)
|
|
28
|
+
fresh process / memory_search("交付说明"): 1 hit (scope=project)
|
|
29
|
+
current text: - [project] 本项目的交付说明统一用中文 — 索引摘要
|
|
30
|
+
history source: synthetic-demo-write:1; quote: 记住:本项目的交付说明统一用中文。
|
|
31
|
+
other project / current + history: 0 + 0 hits
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
当前查询返回有效摘要;另一次 `memory_search({query: "交付说明", mode: "exact", view: "history"})` 返回原话及消息来源,历史内容不能当作当前指令。以上六行是工具结果摘要,完整返回值和局限见[运行记录](docs/runs/2026-11-07-source-recall.md)。在源码目录运行 `node scripts/demo-source-recall.mjs` 可复现;真正的[换聊天验收](docs/guides/fresh-chat.md)仍需在 DSH 中另做。
|
|
35
|
+
|
|
9
36
|
## 个人资料与按需读取
|
|
10
37
|
|
|
11
38
|
已识别的生日、性别、健康、亲密关系和私人联系方式默认不进入自动索引投影,也不作为无关后台整理或写入审查的旧记忆发送。普通 `memory_search` 默认隐藏这些内容;用户询问相关资料时,才明确使用 `includePrivate: true`。主题文件含有未分段的敏感内容时,普通搜索会保守跳过整个主题文件,安全的索引摘要仍可检索。
|
|
@@ -45,13 +72,9 @@ Markdown 索引和主题正文便于阅读;来源、候选、历史与调用
|
|
|
45
72
|
|
|
46
73
|
## 安装与卸载
|
|
47
74
|
|
|
48
|
-
|
|
75
|
+
使用上方[先试起来](#先试起来)的 DeepSeek Harness 官方插件管理器命令安装。代码为可直接执行的 ESM,无安装时构建脚本,也不需要 npm 账户。
|
|
49
76
|
|
|
50
|
-
|
|
51
|
-
dsh plugin --profile desktop add github:OakcoderX/solopup-memory#v0.21.0-beta.3 --ignore-scripts
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
以上固定本次修复版本;需要不可变 Git 来源时,用发行页的完整提交 SHA 替换标签。npm 发布可能晚于 GitHub,请先核对注册表和发行说明,再使用 `dsh plugin --profile desktop add solopup-memory@0.21.0-beta.3 --ignore-scripts`;旧的 `beta` 标签可能仍指向先前版本。也可下载发行页的 `.tgz`,使用 `dsh plugin --profile desktop add /absolute/path/to/solopup-memory-0.21.0-beta.3.tgz --offline --ignore-scripts`。
|
|
77
|
+
`beta` 标签跟随已公开并完成下载核验的测试版。需要固定版本时,从发行页选择准确版本号,例如 `solopup-memory@0.21.0-beta.3`;Git 安装也可用 `dsh plugin --profile desktop add github:OakcoderX/solopup-memory#v0.21.0-beta.3 --ignore-scripts`,需要不可变 Git 来源时,用发行页的完整提交 SHA 替换标签。也可下载发行页的 `.tgz`,使用 `dsh plugin --profile desktop add /absolute/path/to/solopup-memory-0.21.0-beta.3.tgz --offline --ignore-scripts`。
|
|
55
78
|
|
|
56
79
|
已安装旧名 `dsh-memory` 时,先完成完整备份、关闭使用该库的宿主,用官方管理器移除旧包,再安装新包;不要同时启用两个记忆插件。新名字继续使用原记忆库和控制格式。
|
|
57
80
|
|
|
@@ -97,8 +120,16 @@ MIT License,Copyright © 2026 oakfilm。产品品牌:SoloPup Memory。
|
|
|
97
120
|
|
|
98
121
|
## 开发验证
|
|
99
122
|
|
|
123
|
+
测试集中在 `test/`,运行时模块保持原路径。`npm test` 和安装包都保留完整的显式测试集合。
|
|
124
|
+
|
|
100
125
|
```sh
|
|
101
126
|
npm test
|
|
127
|
+
node scripts/detect.mjs --check # L0 不变量检测(只读);有 error 退出码 1
|
|
128
|
+
node eval/semantic-suite.mjs # L2 管道保真层(10 条冻结用例)
|
|
129
|
+
node eval/bench-detect.mjs # 对比实验:检测器召回与耗时
|
|
130
|
+
node scripts/dream.mjs # 做梦 P0 影子计划(只读)
|
|
131
|
+
node scripts/security-check.mjs # 发版前机械安全自查
|
|
132
|
+
node scripts/soak.mjs # 可靠性测试:官方安装 + 真实宿主多轮 + 崩溃恢复
|
|
102
133
|
node scripts/verify.mjs --no-accept
|
|
103
134
|
node accept.mjs --profile desktop
|
|
104
135
|
```
|
package/RELEASE.md
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
# 0.22.0-beta.3 — DSH 0.2.2 compatibility and first-run integration
|
|
2
|
+
|
|
3
|
+
**Source candidate, not a published beta.** This version integrates the unmerged onboarding/test-layout work with current main and waits for DSH asynchronous Session Projection registration before exposing dependent features. New hosts use retained projection handles; older hosts retain their registry-reader path. Existing beta tags and the published registry version are not rewritten.
|
|
4
|
+
|
|
5
|
+
The isolated Linux host checks use the official npm CLI distributions for DSH 0.2.1-rc.5 and 0.2.2-rc.1, synthetic Sessions, no user profile or credentials, and no model calls. They cover six-tool activation, live projection state, exact removal of obsolete memory sections while preserving other content, cold replay, rejected registrations and owner disposal. This is not real-model semantic acceptance or daily desktop verification. See [COMPATIBILITY.md](COMPATIBILITY.md) and the integration receipt for exact results and remaining gates.
|
|
6
|
+
|
|
7
|
+
# 0.22.0-beta.2 — detection layer, semantic pipeline gate, dream P0/P1
|
|
8
|
+
|
|
9
|
+
**Source update, not a published beta.** (v0.22.0-beta.1 tag failed before submission because npm 11 parsed the relative tarball path as a GitHub shorthand; no npm version was published. This beta.2 commit fixes the path and passes the same gates.) This commit adds engineering infrastructure and read-only/planning features; it does not claim stable semantic acceptance or publish to npm/market. Published version remains 0.21.0-beta.3.
|
|
10
|
+
|
|
11
|
+
- L0 detection: `detect.mjs` + `scripts/detect.mjs` read-only invariant checks (index format, projection consistency, anchors, withdrawal residue, duplicates/conflicts, budgets, scope, version drift, topic structure, duplicate stores). `memory_status` exposes a bounded `lint` summary.
|
|
12
|
+
- L2 pipeline-fidelity suite: 10 frozen cases (~190ms) checking that a correct or deliberately wrong candidate keeps its conditions/meaning/expiry/scope through write → projection → retrieval. `semanticTruthEvaluated` stays false (no real extraction model run).
|
|
13
|
+
- L3 telemetry: capture success rate, zero-output days, stale pending candidates, short-session skips.
|
|
14
|
+
- Dream P0 shadow plan: read-only op list from L0+L3 with evidence, zero model calls. Dream P1 applies only `compact-index` (reuses deterministic `pruneStore`) behind `--reviewed <planHash>`, after a file backup, with post-apply L0 verification; every other op remains human-only.
|
|
15
|
+
- Short sessions below the auto-capture turn threshold now emit `capture/skipped/short-session-below-threshold` instead of silently losing context.
|
|
16
|
+
- Add a mechanical security self-check (`scripts/security-check.mjs`, wired into `verify`): zero runtime dependencies and install hooks; no runtime network calls or listening sockets; the single subprocess is `restore.mjs` invoking fixed-argument `tar` without a shell; no secrets or machine absolute paths in shipped files; workflow actions pinned to commit SHAs with `contents: read`, no `secrets.*` and no `pull_request_target`; package contents exclude research/logs/tarballs; MIT license, engines and `.gitignore` present.
|
|
17
|
+
- Add a reliability test (`scripts/soak.mjs`) on the official offline install path: repeated real DSH host start/stop, SIGKILL recovery with no leftover `.write.lock`/`.publication.json`, two concurrent hosts on one store followed by a clean reload, unchanged memory content files across cycles, and store permissions 0700 (files 0600).
|
|
18
|
+
|
|
19
|
+
Known gaps: no real-model semantic acceptance; no per-memory usage counters; dream P1 does not apply merges, conflict arbitration or transcript-based corrections.
|
|
20
|
+
|
|
21
|
+
# 0.21.0-beta.4 — automated beta release infrastructure
|
|
22
|
+
|
|
23
|
+
This maintenance version adds the repository release workflow, OIDC publishing support, immutable artifact checks and post-publish GitHub/market updates. Memory behavior and data formats are unchanged. Hosted workflow success and trusted-publisher validation must be checked in the release receipts; a workflow file alone does not establish them. Stable semantic acceptance and historical erasure remain outside this release.
|
|
24
|
+
|
|
25
|
+
## Historical beta.3 release evidence
|
|
26
|
+
|
|
1
27
|
# 0.21.0-beta.3 - private-memory exposure reduction
|
|
2
28
|
|
|
3
29
|
Public beta. Conservative known-category filtering, not full privacy isolation or stable semantic acceptance.
|
package/SECURITY.md
CHANGED
|
@@ -75,3 +75,10 @@
|
|
|
75
75
|
## beta.3 privacy boundary
|
|
76
76
|
|
|
77
77
|
Recognized private records, including their quoted evidence, are omitted from automatic projection and unrelated saved-memory contexts. The classifier is heuristic and incomplete; explicit [private] or [private:category] text is conservatively treated as on-demand. Searches default to excluding recognized private content; includePrivate=true is a disclosure control, not a user authentication boundary. Other tools can read the raw files. Private facts explicitly present in the current conversation or prior ordinary messages remain in that conversation. Existing append-only archives, caches, exports, backups and provider-side copies are not purged. Never claim that hiding an index or memory_forget erases those copies. Physical raw-index migration and reviewed local erasure are separate work.
|
|
78
|
+
|
|
79
|
+
## 发版前机械自查(0.22.0-beta.1 起)
|
|
80
|
+
|
|
81
|
+
`node scripts/security-check.mjs` 只读检查发行面的机械项:零运行时依赖与安装钩子、运行时无网络/监听面、唯一子进程是 `restore.mjs` 以固定参数调用 `tar`(无 shell)、发行文件无密钥与机器绝对路径、工作流 action 按 commit pin 且权限为 `contents: read`、无 `secrets.*`/`pull_request_target`、发行包不含研究目录与日志、MIT 许可与引擎声明。
|
|
82
|
+
|
|
83
|
+
这不是独立安全审计,也不覆盖:依赖供应链以外的攻击、宿主自身的模型/网络行为、物理访问、已知的隐私分类器不完整、以及“记忆被用户自己手工编辑”的情形。可靠性验证见 `node scripts/soak.mjs`(官方离线安装 + 真实宿主多轮启停 + SIGKILL 恢复 + 并发宿主 + 数据指纹不变)。
|
|
84
|
+
|
package/context-history.mjs
CHANGED
|
@@ -90,8 +90,25 @@ export function assertCurrentMemoryRequest(messages,currentText) {
|
|
|
90
90
|
|
|
91
91
|
export function setupMemoryHistory(ctx,render) {
|
|
92
92
|
const projections = optionalService(ctx, 'sessionProjections')
|
|
93
|
-
if(typeof projections?.register!=='function'
|
|
94
|
-
projections.register(memoryContextProjection())
|
|
93
|
+
if(typeof projections?.register!=='function')return{available:false,observe:()=>{}}
|
|
94
|
+
const registration=projections.register(memoryContextProjection())
|
|
95
|
+
// DSH 0.2.2 returns a callable thenable. Await it before publishing hooks,
|
|
96
|
+
// while retaining synchronous support for the older registry API.
|
|
97
|
+
const ready=handle=>{
|
|
98
|
+
// Disposal can win after the host resolves registration but before this
|
|
99
|
+
// continuation runs. The owning fiber already releases its registration.
|
|
100
|
+
if(ctx.fiber?.uid===null)return{available:false,observe:()=>{}}
|
|
101
|
+
return installMemoryHistory(ctx,render,typeof handle?.stateOf==='function'
|
|
102
|
+
? session=>handle.stateOf(session)
|
|
103
|
+
: typeof projections.stateOf==='function'
|
|
104
|
+
? session=>projections.stateOf(session,HISTORY_PROJECTION_KEY)
|
|
105
|
+
: undefined)
|
|
106
|
+
}
|
|
107
|
+
return typeof registration?.then==='function'?Promise.resolve(registration).then(ready):ready(registration)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function installMemoryHistory(ctx,render,stateOf) {
|
|
111
|
+
if(!stateOf)fail('memory-context-reader-unavailable')
|
|
95
112
|
const sessions=new Map()
|
|
96
113
|
const cwdFor=(session,fallback)=>typeof ctx.workingDirectory?.get==='function'?ctx.workingDirectory.get(session):fallback
|
|
97
114
|
const refresh=(input,next)=>{
|
|
@@ -99,7 +116,7 @@ export function setupMemoryHistory(ctx,render) {
|
|
|
99
116
|
if(!session)fail('memory-context-session-unavailable')
|
|
100
117
|
const cwd=cwdFor(session)
|
|
101
118
|
sessions.set(session.id,{ref:new WeakRef(session),cwd})
|
|
102
|
-
reconcileMemoryContext(session,
|
|
119
|
+
reconcileMemoryContext(session,stateOf(session),render(cwd))
|
|
103
120
|
return next()
|
|
104
121
|
}
|
|
105
122
|
// Run before pre-step consumers (including summarizers), then recheck at
|