@modusensus/dsh-mneme 0.7.3 → 0.7.5

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 (145) hide show
  1. package/.github/workflows/test.yml +32 -0
  2. package/CHANGELOG.md +89 -0
  3. package/CONTRIBUTING.md +245 -0
  4. package/README.md +159 -419
  5. package/SECURITY.md +674 -0
  6. package/docs/devlog/2026-08-14-dsh-mneme-dev-log.md +247 -0
  7. package/docs/devlog/2026-08-15-dsh-mneme-audit-stress-dev-log.md +145 -0
  8. package/docs/devlog/2026-08-15-dsh-mneme-pipeline-dev-log.md +56 -0
  9. package/docs/devlog/2026-08-15-dsh-mneme-reflection-dev-log.md +77 -0
  10. package/docs/devlog/2026-08-15-dsh-mneme-review-fixes-dev-log.md +64 -0
  11. package/docs/devlog/2026-08-15-dsh-mneme-semantic-dev-log.md +90 -0
  12. package/dsh-mneme/CHANGELOG.md +358 -0
  13. package/dsh-mneme/LICENSE +21 -0
  14. package/dsh-mneme/README.md +493 -0
  15. package/dsh-mneme/docs/AGENT_MEMORY_RESEARCH.md +183 -0
  16. package/dsh-mneme/docs/ENTITIES.md +245 -0
  17. package/dsh-mneme/docs/LOCAL_MODEL.md +141 -0
  18. package/dsh-mneme/docs/MIGRATION.md +127 -0
  19. package/dsh-mneme/docs/SEMANTIC.md +256 -0
  20. package/dsh-mneme/docs/SLEEP.md +163 -0
  21. package/{src → dsh-mneme/lib}/api.js +15 -0
  22. package/{lib → dsh-mneme/lib}/client.js +192 -3
  23. package/{lib → dsh-mneme/lib}/config.js +7 -0
  24. package/{lib → dsh-mneme/lib}/inject.js +20 -3
  25. package/{lib → dsh-mneme/lib}/mirror.js +3 -1
  26. package/{lib → dsh-mneme/lib}/quality-filter.js +3 -1
  27. package/{src → dsh-mneme/lib}/service.js +9 -5
  28. package/{lib → dsh-mneme/lib}/store.js +35 -1
  29. package/{lib → dsh-mneme/lib}/summarize.js +2 -2
  30. package/{src → dsh-mneme/lib}/tools.js +3 -3
  31. package/dsh-mneme/package-lock.json +1936 -0
  32. package/dsh-mneme/package.json +83 -0
  33. package/{lib → dsh-mneme/src}/api.js +15 -0
  34. package/{src → dsh-mneme/src}/config.js +7 -0
  35. package/{src → dsh-mneme/src}/inject.js +20 -3
  36. package/{src → dsh-mneme/src}/mirror.js +3 -1
  37. package/{src → dsh-mneme/src}/quality-filter.js +3 -1
  38. package/{lib → dsh-mneme/src}/service.js +9 -5
  39. package/{src → dsh-mneme/src}/store.js +35 -1
  40. package/{src → dsh-mneme/src}/summarize.js +2 -2
  41. package/{lib → dsh-mneme/src}/tools.js +3 -3
  42. package/{test → dsh-mneme/test}/config.test.js +7 -0
  43. package/{test → dsh-mneme/test}/inject.test.js +57 -0
  44. package/dsh-mneme/test/layered-types-stats.test.js +144 -0
  45. package/package.json +18 -43
  46. package//346/250/252/345/271/205.png +0 -0
  47. /package/{cordis.patch.yml → dsh-mneme/cordis.patch.yml} +0 -0
  48. /package/{lib → dsh-mneme/lib}/commands.js +0 -0
  49. /package/{lib → dsh-mneme/lib}/dream/clustering.js +0 -0
  50. /package/{lib → dsh-mneme/lib}/dream/decisions.js +0 -0
  51. /package/{lib → dsh-mneme/lib}/dream/sleep.js +0 -0
  52. /package/{lib → dsh-mneme/lib}/dream/tag-extractor.js +0 -0
  53. /package/{lib → dsh-mneme/lib}/dream.js +0 -0
  54. /package/{lib → dsh-mneme/lib}/embedding.js +0 -0
  55. /package/{lib → dsh-mneme/lib}/entities/extractor.js +0 -0
  56. /package/{lib → dsh-mneme/lib}/heat.js +0 -0
  57. /package/{lib → dsh-mneme/lib}/hot-memory.js +0 -0
  58. /package/{lib → dsh-mneme/lib}/index.js +0 -0
  59. /package/{lib → dsh-mneme/lib}/local-embedder.js +0 -0
  60. /package/{lib → dsh-mneme/lib}/parser/tag.js +0 -0
  61. /package/{lib → dsh-mneme/lib}/parser/wiki-link.js +0 -0
  62. /package/{lib → dsh-mneme/lib}/reranker.js +0 -0
  63. /package/{lib → dsh-mneme/lib}/search/adaptive.js +0 -0
  64. /package/{lib → dsh-mneme/lib}/search/bm25.js +0 -0
  65. /package/{lib → dsh-mneme/lib}/search/tag-boost.js +0 -0
  66. /package/{lib → dsh-mneme/lib}/settings.js +0 -0
  67. /package/{lib → dsh-mneme/lib}/vector-index.js +0 -0
  68. /package/{scripts → dsh-mneme/scripts}/benchmark-embed.js +0 -0
  69. /package/{scripts → dsh-mneme/scripts}/benchmark-recall.js +0 -0
  70. /package/{scripts → dsh-mneme/scripts}/benchmark-rerank.js +0 -0
  71. /package/{scripts → dsh-mneme/scripts}/e2e-dsh.js +0 -0
  72. /package/{scripts → dsh-mneme/scripts}/stress-dsh.js +0 -0
  73. /package/{scripts → dsh-mneme/scripts}/sync-lib.js +0 -0
  74. /package/{src → dsh-mneme/src}/commands.js +0 -0
  75. /package/{src → dsh-mneme/src}/dream/clustering.js +0 -0
  76. /package/{src → dsh-mneme/src}/dream/decisions.js +0 -0
  77. /package/{src → dsh-mneme/src}/dream/sleep.js +0 -0
  78. /package/{src → dsh-mneme/src}/dream/tag-extractor.js +0 -0
  79. /package/{src → dsh-mneme/src}/dream.js +0 -0
  80. /package/{src → dsh-mneme/src}/embedding.js +0 -0
  81. /package/{src → dsh-mneme/src}/entities/extractor.js +0 -0
  82. /package/{src → dsh-mneme/src}/heat.js +0 -0
  83. /package/{src → dsh-mneme/src}/hot-memory.js +0 -0
  84. /package/{src → dsh-mneme/src}/index.js +0 -0
  85. /package/{src → dsh-mneme/src}/local-embedder.js +0 -0
  86. /package/{src → dsh-mneme/src}/parser/tag.js +0 -0
  87. /package/{src → dsh-mneme/src}/parser/wiki-link.js +0 -0
  88. /package/{src → dsh-mneme/src}/reranker.js +0 -0
  89. /package/{src → dsh-mneme/src}/search/adaptive.js +0 -0
  90. /package/{src → dsh-mneme/src}/search/bm25.js +0 -0
  91. /package/{src → dsh-mneme/src}/search/tag-boost.js +0 -0
  92. /package/{src → dsh-mneme/src}/settings.js +0 -0
  93. /package/{src → dsh-mneme/src}/vector-index.js +0 -0
  94. /package/{test → dsh-mneme/test}/api.test.js +0 -0
  95. /package/{test → dsh-mneme/test}/audit.test.js +0 -0
  96. /package/{test → dsh-mneme/test}/benchmark.test.js +0 -0
  97. /package/{test → dsh-mneme/test}/boundary-v0625.test.js +0 -0
  98. /package/{test → dsh-mneme/test}/client.test.js +0 -0
  99. /package/{test → dsh-mneme/test}/clustering.test.js +0 -0
  100. /package/{test → dsh-mneme/test}/commands.test.js +0 -0
  101. /package/{test → dsh-mneme/test}/conflict-freeze.test.js +0 -0
  102. /package/{test → dsh-mneme/test}/directory.test.js +0 -0
  103. /package/{test → dsh-mneme/test}/dream.test.js +0 -0
  104. /package/{test → dsh-mneme/test}/entities.test.js +0 -0
  105. /package/{test → dsh-mneme/test}/epistemic.test.js +0 -0
  106. /package/{test → dsh-mneme/test}/fnew-0112.test.js +0 -0
  107. /package/{test → dsh-mneme/test}/fnew-03.test.js +0 -0
  108. /package/{test → dsh-mneme/test}/graph-api.test.js +0 -0
  109. /package/{test → dsh-mneme/test}/heat.test.js +0 -0
  110. /package/{test → dsh-mneme/test}/helpers/dream-mock.js +0 -0
  111. /package/{test → dsh-mneme/test}/hot-memory.test.js +0 -0
  112. /package/{test → dsh-mneme/test}/llm-audit.test.js +0 -0
  113. /package/{test → dsh-mneme/test}/local-embedder.test.js +0 -0
  114. /package/{test → dsh-mneme/test}/mirror-dirty.test.js +0 -0
  115. /package/{test → dsh-mneme/test}/mirror-edit-digest.test.js +0 -0
  116. /package/{test → dsh-mneme/test}/mirror-generation.test.js +0 -0
  117. /package/{test → dsh-mneme/test}/mirror.test.js +0 -0
  118. /package/{test → dsh-mneme/test}/normalize-decisions.test.js +0 -0
  119. /package/{test → dsh-mneme/test}/peer-blockers.test.js +0 -0
  120. /package/{test → dsh-mneme/test}/policy-epoch.test.js +0 -0
  121. /package/{test → dsh-mneme/test}/provenance.test.js +0 -0
  122. /package/{test → dsh-mneme/test}/quality-filter.test.js +0 -0
  123. /package/{test → dsh-mneme/test}/reasoning-effort.test.js +0 -0
  124. /package/{test → dsh-mneme/test}/recall-evals.test.js +0 -0
  125. /package/{test → dsh-mneme/test}/recall-layer.test.js +0 -0
  126. /package/{test → dsh-mneme/test}/recall-runs.test.js +0 -0
  127. /package/{test → dsh-mneme/test}/receipt-chain.test.js +0 -0
  128. /package/{test → dsh-mneme/test}/reflection.test.js +0 -0
  129. /package/{test → dsh-mneme/test}/reranker.test.js +0 -0
  130. /package/{test → dsh-mneme/test}/search-fusion.test.js +0 -0
  131. /package/{test → dsh-mneme/test}/semantic.test.js +0 -0
  132. /package/{test → dsh-mneme/test}/service-search.test.js +0 -0
  133. /package/{test → dsh-mneme/test}/service.test.js +0 -0
  134. /package/{test → dsh-mneme/test}/settings.test.js +0 -0
  135. /package/{test → dsh-mneme/test}/sleep-heat.test.js +0 -0
  136. /package/{test → dsh-mneme/test}/sleep.test.js +0 -0
  137. /package/{test → dsh-mneme/test}/store.test.js +0 -0
  138. /package/{test → dsh-mneme/test}/stress.test.js +0 -0
  139. /package/{test → dsh-mneme/test}/summarize.test.js +0 -0
  140. /package/{test → dsh-mneme/test}/tag-boost.test.js +0 -0
  141. /package/{test → dsh-mneme/test}/tag.test.js +0 -0
  142. /package/{test → dsh-mneme/test}/tools.test.js +0 -0
  143. /package/{test → dsh-mneme/test}/updated-at-semantics.test.js +0 -0
  144. /package/{test → dsh-mneme/test}/vector-index.test.js +0 -0
  145. /package/{test → dsh-mneme/test}/wiki-link.test.js +0 -0
package/SECURITY.md ADDED
@@ -0,0 +1,674 @@
1
+ # Security Policy
2
+
3
+ > **English** | [中文](#安全策略)
4
+
5
+ ---
6
+
7
+ ## Supported Versions
8
+
9
+ We actively maintain the latest minor version. Security fixes are backported to the latest patch release, and critical fixes may be backported to the previous minor version.
10
+
11
+ | Version | Supported | Status |
12
+ |---|---|---|
13
+ | 0.7.x | ✅ Yes | Active development |
14
+ | 0.6.x | ⚠️ Best-effort | Critical fixes only |
15
+ | < 0.6.0 | ❌ No | Please upgrade to 0.7.x |
16
+
17
+ **End-of-life notice**: 0.6.x is in best-effort maintenance (critical fixes only). Its end-of-life date will be announced in advance; after that date no security fixes will be provided for 0.6.x.
18
+
19
+ ---
20
+
21
+ ## Known Security Features
22
+
23
+ The following security features are implemented and maintained in the project:
24
+
25
+ | Feature | Description | Status |
26
+ |---|---|---|
27
+ | `apiToken` Authentication | All remote endpoints require `Authorization: Bearer <apiToken>` when a token is configured; comparison uses `crypto.timingSafeEqual` | ✅ Implemented |
28
+ | `policyEpoch` Memory Governance | Bumping `policyEpoch` downgrades all prior `dream_runs` to historical evidence; their receipts no longer drive real-time memory decisions | ✅ Implemented |
29
+ | `conflictFreezeEnabled` Conflict Freeze | Conflicting memories are not auto-merged; they are flagged as pending human review, preserving data integrity | ✅ Implemented |
30
+ | CAS (Compare-and-Swap) Guard | Prevents concurrent write conflicts; ensures atomic write operations | ✅ Implemented |
31
+ | Digest Baseline Audit | Memory updates are compared against digest baselines to detect unauthorized changes | ✅ Implemented |
32
+ | `failure_memories` Audit Trail | Every failed write operation is logged for forensic analysis | ✅ Implemented |
33
+ | `recall_run` Search Audit | Every search operation is recorded with timestamp and query metadata | ✅ Implemented |
34
+ | Local-First Data Processing | All embeddings, reranking, and memory consolidation run locally; no data leaves the device | ✅ Implemented |
35
+ | No Telemetry | No analytics, no remote logging, no network requests by design | ✅ Implemented |
36
+ | Query Sanitization | LIKE-query escaping, bounded paging, and Markdown mirror escaping prevent injection and malformed input | ✅ Implemented |
37
+ | `entityExtractionEnabled` Opt-In Entity Extraction | Entity extraction is opt-in via configuration (default: off), minimizing data processing by default | ✅ Implemented |
38
+ | Graceful Degradation | System falls back to keyword search on component failure; no crash | ✅ Implemented |
39
+ | Human-Editable Mirrors | All memories mirrored to Markdown files; users can verify and reconstruct data | ✅ Implemented |
40
+ | Mirror Generation CAS/Fence | Mirror sync is bound to a monotonic `generation` counter with CAS/fence semantics; stale or concurrent mirror writes are rejected | ✅ Implemented |
41
+ | Crash-Recovery Debt Model | Business writes atomically bump `desired generation` in the same transaction; after a crash, `recoverMirror` replays the debt instead of silently skipping repairs | ✅ Implemented |
42
+ | `/health` Auth-Gated Endpoint | Health endpoint requires `apiToken`; error codes are sanitized (no-space / permission / sync-failed) and read failures fail closed as `unknown` | ✅ Implemented |
43
+ | Fail-Closed Input Validation | Generation counters and hot-memory parameters are validated (`Number.isInteger`, finite, non-negative) with SQL `CHECK` constraints; invalid input falls back to safe defaults or is rejected | ✅ Implemented |
44
+ | Hybrid Score Clamping | Hybrid fusion scores are clamped to [0, 1] to prevent vector + BM25 stacking from breaking normalization bounds | ✅ Implemented |
45
+ | Tag Sanitization | Tag normalization reuses the sanitizer; `autoTag` skips forgotten memories; `setMemoryTags` runs inside a SAVEPOINT for atomic rollback | ✅ Implemented |
46
+
47
+ ---
48
+
49
+ ## Reporting a Vulnerability
50
+
51
+ ### Please DO NOT
52
+
53
+ - Open a public issue for security vulnerabilities
54
+ - Post exploit details in discussions or comments
55
+ - Submit PRs that expose security flaws without prior coordination
56
+
57
+ ### Please DO
58
+
59
+ 1. **Email** `guanqishi26@gmail.com` (or open a **private security advisory** via [GitHub Security Advisories](https://github.com/modusensus/dsh-mneme/security/advisories))
60
+ 2. Include:
61
+ - A clear description of the vulnerability
62
+ - Steps to reproduce (minimal test case preferred)
63
+ - Impact assessment (data exposure? local-only? remote?)
64
+ - Affected versions
65
+ - Your proposed fix (if any)
66
+ - Whether you are requesting credit / disclosure preferences
67
+
68
+ ### Response Timeline
69
+
70
+ | Phase | Time | Action |
71
+ |---|---|---|
72
+ | Acknowledgment | Within 48 hours | We confirm receipt and assign a tracking ID |
73
+ | Initial Assessment | Within 7 days | We validate severity and scope; we may request additional information |
74
+ | Fix Development | Severity-dependent | Critical: ≤ 14 days; High: ≤ 30 days; Medium/Low: next release |
75
+ | Validation & Testing | 1–3 days after fix | We run regression and security tests on the patch |
76
+ | Coordinated Disclosure | At fix release | We publish a security advisory and release patch simultaneously |
77
+
78
+ **Note**: For Critical vulnerabilities, if a full fix cannot be developed within 14 days, we will provide a temporary mitigation or workaround within that timeframe.
79
+
80
+ ### Severity Classification
81
+
82
+ We follow the [CVSS v3.1](https://www.first.org/cvss/v3.1/specification-document) standard:
83
+
84
+ - **Critical** (9.0–10.0): Remote code execution, unauthorized data exfiltration, bypass of core security controls
85
+ - **High** (7.0–8.9): Local privilege escalation, significant data integrity compromise, DoS with high impact
86
+ - **Medium** (4.0–6.9): Information disclosure under specific conditions, partial bypass of controls
87
+ - **Low** (0.1–3.9): Minor information leakage, defense-in-depth improvements
88
+
89
+ ---
90
+
91
+ ## Security Design Principles
92
+
93
+ ### 1. Local-First, Zero-Network
94
+
95
+ - All embeddings, reranking, and memory consolidation run locally
96
+ - Memory text **never** leaves the device
97
+ - No telemetry, no analytics, no remote logging
98
+
99
+ ### 2. Fail-Safe by Default
100
+
101
+ - Any component failure (LLM, embedder, reranker) degrades gracefully to keyword search
102
+ - Malformed input never crashes the plugin or corrupts the database
103
+ - Concurrent write conflicts are resolved via CAS (compare-and-swap) guards
104
+
105
+ ### 3. Audit Everything
106
+
107
+ - Every `autoDream` run generates a cryptographically verifiable receipt
108
+ - Every memory update creates a `failure_memories` audit trail
109
+ - Every search records a `recall_run` for later inspection
110
+
111
+ ### 4. Human Sovereignty
112
+
113
+ - All memories are mirrored to human-editable Markdown files
114
+ - Machine writes vs. human edits are distinguished via digest baselines
115
+ - Users can fully reconstruct the database from Markdown mirrors alone
116
+
117
+ ### 5. Minimal Remote Surface
118
+
119
+ - Remote API endpoints are opt-in: they require a configured `apiToken`
120
+ - When a token is set, every remote request is checked with a timing-safe comparison
121
+ - When no token is set, remote endpoints are effectively disabled; all processing stays local
122
+
123
+ ---
124
+
125
+ ## Dependency Vulnerability Handling
126
+
127
+ ### Process
128
+
129
+ We follow a 5-step process for handling third-party dependency vulnerabilities:
130
+
131
+ | Step | Action | Timeframe | Tooling |
132
+ |---|---|---|---|
133
+ | 1. Scan | Continuous automated scanning of all runtime and development dependencies | Automated (daily) | OrbisAI Security, npm audit |
134
+ | 2. Assess | For each detected vulnerability, assess severity, exploitability, and impact on dsh-mneme | Within 48 hours of detection | CVSS v3.1, manual code analysis |
135
+ | 3. Report | Document findings in the security tracker; report to maintainers | Immediately after assessment | Security tracker, maintainer channel |
136
+ | 4. Fix | Upgrade dependency to a patched version or apply mitigation | Critical: ≤ 14 days; High: ≤ 30 days; Medium/Low: next release | npm/pnpm update, manual patching |
137
+ | 5. Disclose | Publish security advisory with details and fixed version | At release of fixed version | GitHub Security Advisories + npm release notes |
138
+
139
+ ### Third-Party Dependency Policy
140
+
141
+ - All new runtime dependencies must pass a security review before inclusion
142
+ - Dependencies with known critical vulnerabilities that cannot be fixed within the timeline will be replaced with alternatives
143
+ - Dependency lockfiles (`package-lock.json`) are committed and reviewed in PRs
144
+
145
+ ### Recent Dependency Fixes
146
+
147
+ | CVE | Package | Version (Before) | Version (After) | Severity | Fixed In |
148
+ |---|---|---|---|---|---|
149
+ | CVE-2026-39244 | `adm-zip` | 0.5.18 | 0.6.0 | High | v0.3.4 |
150
+
151
+ ---
152
+
153
+ ## Security Audit History
154
+
155
+ ### v0.2.10 — Security Hardening
156
+
157
+ | ID | Finding | Severity | Status |
158
+ |---|---|---|---|
159
+ | F-NEW-01 | Concurrent write race on `store.js` | **Critical** | ✅ Fixed (CAS guard + atomic write) |
160
+ | F-NEW-02 | Transactional inconsistency during mirror sync | **High** | ✅ Fixed (transactional mirror + rollback) |
161
+ | F-NEW-03 | Mirror health state not validated before overwrite | **High** | ✅ Fixed (digest baseline + FSM validation) |
162
+
163
+ ### v0.3.4 — Dependency Security
164
+
165
+ | CVE | Package | Severity | Status |
166
+ |---|---|---|---|
167
+ | CVE-2026-39244 | `adm-zip` 0.5.18 | **High** | ✅ Fixed (upgraded to 0.6.0) |
168
+
169
+ ### v0.3.6 — Mirror Debt Modeling (audit peer re-verification)
170
+
171
+ | Finding | Severity | Status |
172
+ |---|---|---|
173
+ | Mirror sync not bound to a generation counter (stale overwrite window) | **High** | ✅ Fixed (generation + CAS/fence semantics, per-type status) |
174
+ | `/health` endpoint unauthenticated with verbose error codes | **High** | ✅ Fixed (auth-gated, sanitized codes, fail-closed `unknown`) |
175
+ | COMMIT-crash window could permanently skip mirror repairs | **High** | ✅ Fixed (recoverMirror triggers on dirty OR generation > applied) |
176
+
177
+ ### v0.3.8 — Mirror Sync Reliability (peer 6 blockers)
178
+
179
+ | Finding | Severity | Status |
180
+ |---|---|---|
181
+ | Silent mirror sync failures (no error surfaced to write path) | **High** | ✅ Fixed (`syncMirror` returns `{success, error}`; `afterSync` check on write entry) |
182
+ | Non-atomic generation increments under multi-process concurrency | **High** | ✅ Fixed (`UPDATE ... RETURNING` atomic statement + `PRAGMA busy_timeout=5000`) |
183
+ | Generation counter overflow / negative values | **Medium** | ✅ Fixed (JS validation + SQL `CHECK(0..MAX_SAFE_INTEGER)`) |
184
+
185
+ ### v0.3.9 — Audit A/B/D/F
186
+
187
+ | Finding | Severity | Status |
188
+ |---|---|---|
189
+ | CAS update and generation increment not in the same transaction | **High** | ✅ Fixed (atomic `runAtomically`; miss does not increment) |
190
+ | Failed updates could report success | **High** | ✅ Fixed (degraded/pending receipts with mirror attributes) |
191
+ | Generation validation not fail-closed | **Medium** | ✅ Fixed (`Number.isInteger` fail-closed + migration detects stale dirty values) |
192
+
193
+ ### v0.5.1 — Hot Memory Parameter Defense
194
+
195
+ | Finding | Severity | Status |
196
+ |---|---|---|
197
+ | Negative / non-finite `maxRounds`/`maxTokens` could trigger a synchronous infinite loop via public API | **High** | ✅ Fixed (fallback to safe defaults 5/2000) |
198
+ | Hybrid fusion score could exceed 1.0 (vector + BM25 stacking) | **Medium** | ✅ Fixed (clamp to [0, 1]) |
199
+
200
+ ### v0.6.5 — Tag System Hardening
201
+
202
+ | Finding | Severity | Status |
203
+ |---|---|---|
204
+ | `autoTag` could tag forgotten memories | **Medium** | ✅ Fixed (filter `forgotten` before tagging) |
205
+ | Tag normalization bypassed the sanitizer | **Medium** | ✅ Fixed (reuse `sanitize` in `normalizeTags`) |
206
+ | `setMemoryTags` not atomic on failure | **Medium** | ✅ Fixed (SAVEPOINT rollback) |
207
+
208
+ ### Ongoing
209
+
210
+ - Automated dependency scanning via **OrbisAI Security**
211
+ - Community security reviews welcome via private advisory
212
+
213
+ ---
214
+
215
+ ## Security Advisory Channels
216
+
217
+ Security advisories are published through the following channels simultaneously:
218
+
219
+ 1. **[GitHub Security Advisories](https://github.com/modusensus/dsh-mneme/security/advisories)** — primary channel with detailed technical information
220
+ 2. **[npm Releases](https://www.npmjs.com/package/@modusensus/dsh-mneme)** — release notes include security advisories and fix summaries
221
+
222
+ To receive security notifications:
223
+ - **GitHub**: Watch the repository and enable "Security alerts" in repository settings
224
+ - **npm**: Subscribe to package release notifications for `@modusensus/dsh-mneme`
225
+
226
+ ---
227
+
228
+ ## Disclosure Policy
229
+
230
+ We practice **coordinated disclosure**:
231
+
232
+ 1. Reporter submits vulnerability privately
233
+ 2. We investigate and acknowledge within 48 hours
234
+ 3. We develop fix and prepare advisory (timeline based on severity)
235
+ 4. We notify reporter of fix timeline and planned disclosure date
236
+ 5. We release patch + publish advisory simultaneously
237
+ 6. We credit the reporter (with their consent) in the advisory
238
+
239
+ We do **not** pursue legal action against security researchers who:
240
+ - Act in good faith
241
+ - Do not exploit vulnerabilities beyond proof-of-concept
242
+ - Do not access data belonging to others
243
+ - Allow reasonable time for us to respond before public disclosure
244
+
245
+ **Bug Bounty Policy**: This project does not currently offer monetary rewards. We provide public credit in the advisory (with the reporter's consent).
246
+
247
+ ---
248
+
249
+ ## Security Logs & Data Retention
250
+
251
+ All audit data is stored **locally** in the plugin database and never leaves the device:
252
+
253
+ | Data Type | Storage Location | Notes |
254
+ |---|---|---|
255
+ | `failure_memories` audit logs | Local database | Every failed write is recorded; used for forensic analysis |
256
+ | `recall_run` search logs | Local database | Every search is recorded with timestamp and query metadata |
257
+ | AutoDream receipts | Local database + Markdown mirror | Cryptographically verifiable; persist until user deletes them |
258
+ | Dependency scan reports | OrbisAI Security dashboard | Not stored on device |
259
+
260
+ Retention is user-controlled: audit records live only as long as the local database does. There is no remote logging and no telemetry.
261
+
262
+ ---
263
+
264
+ ## Security-Related Configuration
265
+
266
+ ```yaml
267
+ # Hardened configuration example (all keys below match src/config.js where applicable)
268
+ dsh-mneme:
269
+ # Disable autoDream if you want full manual control
270
+ autoDream: false
271
+
272
+ # Enable conflict freeze for sensitive environments
273
+ conflictFreezeEnabled: true
274
+
275
+ # Use local-only embedding (no network)
276
+ embedProvider: local
277
+
278
+ # Require Authorization: Bearer <apiToken> on remote endpoints (timing-safe)
279
+ apiToken: "set-a-strong-unique-token"
280
+
281
+ # Bump to downgrade all prior dream_runs to historical evidence
282
+ policyEpoch: 1
283
+
284
+ # Keep entity extraction off by default (data minimization)
285
+ entityExtractionEnabled: false
286
+
287
+ # Reranking is opt-in (default: off) — no extra model downloads unless enabled
288
+ rerankEnabled: false
289
+
290
+ # Keep auto-tagging off by default (data minimization)
291
+ autoTagEnabled: false
292
+
293
+ # Disable session lifecycle if you do not need session-scoped disposal
294
+ sessionLifecycleEnabled: false
295
+
296
+ # Disable sleep mode maintenance if you want zero background activity
297
+ sleepModeEnabled: false
298
+
299
+ # Epistemic trust weighting is opt-in (default: off)
300
+ trustEpistemicWeighting: false
301
+
302
+ # LLM audit log retention (days)
303
+ llmAudit:
304
+ enabled: true
305
+ retentionDays: 90
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Contributor Security Guidelines
311
+
312
+ All contributors must comply with the following security requirements:
313
+
314
+ 1. **Dependency Audit**: Run `npm audit` before submitting a PR; newly introduced dependencies must pass security review
315
+ 2. **Secret Scanning**: Never commit API keys, tokens, or credentials to the repository
316
+ 3. **Input Validation**: All user inputs must be validated and sanitized (including LLM-derived content)
317
+ 4. **Secure Code Review**: PRs with security-relevant changes require approval from a maintainer with security expertise
318
+ 5. **Documentation**: New features must include a security impact analysis in the PR description
319
+ 6. **Responsible Disclosure**: Security vulnerabilities found during development must be reported via the appropriate channel, not in public PRs
320
+
321
+ ---
322
+
323
+ ## Contact
324
+
325
+ - **Security Team**: `guanqishi26@gmail.com`
326
+ - **Private Advisory**: [GitHub Security Advisories](https://github.com/modusensus/dsh-mneme/security/advisories)
327
+ - **GPG Key**: Available upon request for encrypted communication
328
+
329
+ ---
330
+
331
+ ## License
332
+
333
+ This project is licensed under the **MIT License**. See [LICENSE](https://github.com/modusensus/dsh-mneme/blob/main/LICENSE) for details.
334
+
335
+ ---
336
+
337
+ # 安全策略
338
+
339
+ > **中文** | [English](#security-policy)
340
+
341
+ ---
342
+
343
+ ## 支持版本
344
+
345
+ 我们积极维护最新的 minor 版本。安全修复会 backport 到最新的 patch 版本,关键修复可能 backport 到前一个 minor 版本。
346
+
347
+ | 版本 | 支持状态 | 说明 |
348
+ |---|---|---|
349
+ | 0.7.x | ✅ 支持 | 活跃开发中 |
350
+ | 0.6.x | ⚠️ 尽力维护 | 仅关键修复 |
351
+ | < 0.6.0 | ❌ 不支持 | 请升级至 0.7.x |
352
+
353
+ **停止维护通知**:0.6.x 处于尽力维护阶段(仅关键修复)。停止维护的具体日期将提前公布;该日期之后将不再提供 0.6.x 的安全修复。
354
+
355
+ ---
356
+
357
+ ## 已知安全特性
358
+
359
+ 项目已实现并维护以下安全特性:
360
+
361
+ | 特性 | 描述 | 状态 |
362
+ |---|---|---|
363
+ | `apiToken` 鉴权 | 配置 token 后,所有远程端点需 `Authorization: Bearer <apiToken>`,比较使用 `crypto.timingSafeEqual` | ✅ 已实现 |
364
+ | `policyEpoch` 记忆治理 | 提升 `policyEpoch` 后,所有先前的 `dream_runs` 降级为历史证据,其 receipt 不再驱动实时记忆决策 | ✅ 已实现 |
365
+ | `conflictFreezeEnabled` 冲突冻结 | 冲突记忆不自动合并,标记为待人工复核,保护数据完整性 | ✅ 已实现 |
366
+ | CAS(比较并交换)守卫 | 防止并发写入冲突,确保原子写操作 | ✅ 已实现 |
367
+ | Digest 基线审计 | 记忆更新与 digest 基线比对,检测未授权修改 | ✅ 已实现 |
368
+ | `failure_memories` 审计轨迹 | 每次写入失败均记录,供取证分析 | ✅ 已实现 |
369
+ | `recall_run` 搜索审计 | 每次搜索操作均记录时间戳和查询元数据 | ✅ 已实现 |
370
+ | 本地优先数据处理 | embedding、rerank、记忆整理均在本地完成,数据不离开设备 | ✅ 已实现 |
371
+ | 无遥测 | 无分析、无远程日志,设计上无网络请求 | ✅ 已实现 |
372
+ | 查询净化 | LIKE 查询转义、分页边界限制、Markdown 镜像转义,防止注入和畸形输入 | ✅ 已实现 |
373
+ | `entityExtractionEnabled` 实体抽取 Opt-In | 实体抽取为配置项、默认关闭(数据最小化原则) | ✅ 已实现 |
374
+ | 优雅降级 | 组件故障时自动回退至关键词搜索,不崩溃 | ✅ 已实现 |
375
+ | 人工可编辑镜像 | 所有记忆镜像至 Markdown 文件,用户可验证和重建数据 | ✅ 已实现 |
376
+ | Mirror Generation CAS/Fence | 镜像同步绑定单调递增的 `generation` 计数器并采用 CAS/fence 语义,拒绝过期或并发镜像写入 | ✅ 已实现 |
377
+ | 崩溃恢复债务模型 | 业务写入在自身事务内原子递增 `desired generation`;崩溃后 `recoverMirror` 依据债务重放修复,不再静默跳过 | ✅ 已实现 |
378
+ | `/health` 鉴权门控 | 健康端点要求 `apiToken`;错误码净化(no-space / permission / sync-failed),读取失败 fail-closed 为 `unknown` | ✅ 已实现 |
379
+ | Fail-Closed 输入校验 | generation 计数与热记忆参数均做 `Number.isInteger`、有限性、非负校验并配 SQL `CHECK` 约束;非法输入回退安全默认值或被拒绝 | ✅ 已实现 |
380
+ | 混合分数钳制 | 混合检索融合分数钳制在 [0, 1],防止向量 + BM25 叠加突破归一化边界 | ✅ 已实现 |
381
+ | Tag 净化 | Tag 规范化复用 sanitizer;`autoTag` 跳过已遗忘记忆;`setMemoryTags` 在 SAVEPOINT 内执行,失败原子回滚 | ✅ 已实现 |
382
+
383
+ ---
384
+
385
+ ## 报告漏洞
386
+
387
+ ### 请不要
388
+
389
+ - 在公开 issue 中披露安全漏洞
390
+ - 在讨论区或评论中发布漏洞利用细节
391
+ - 未经事先协调就提交暴露安全缺陷的 PR
392
+
393
+ ### 请这样做
394
+
395
+ 1. **发送邮件**至 `guanqishi26@gmail.com`(或通过 [GitHub 私有安全公告](https://github.com/modusensus/dsh-mneme/security/advisories) 提交)
396
+ 2. 邮件内容请包含:
397
+ - 漏洞的清晰描述
398
+ - 复现步骤(优先提供最小测试用例)
399
+ - 影响评估(数据泄露?仅本地?远程?)
400
+ - 受影响的版本
401
+ - 你建议的修复方案(如有)
402
+ - 是否要求在公告中署名 / 披露偏好
403
+
404
+ ### 响应时间线
405
+
406
+ | 阶段 | 时间 | 行动 |
407
+ |---|---|---|
408
+ | 确认收到 | 48 小时内 | 我们确认收到并分配追踪 ID |
409
+ | 初步评估 | 7 天内 | 我们验证严重程度和影响范围;可能需要更多信息 |
410
+ | 修复开发 | 按严重程度 | 严重:≤ 14 天;高:≤ 30 天;中/低:下个版本 |
411
+ | 验证与测试 | 修复完成后 1–3 天 | 对补丁进行回归测试和安全测试 |
412
+ | 协调披露 | 修复发布时 | 同时发布安全公告和补丁版本 |
413
+
414
+ **备注**:对于严重漏洞,如果 14 天内无法提供完整修复,我们将在该时间内提供临时缓解措施或替代方案。
415
+
416
+ ### 严重程度分级
417
+
418
+ 我们遵循 [CVSS v3.1](https://www.first.org/cvss/v3.1/specification-document) 标准:
419
+
420
+ - **严重** (9.0–10.0):远程代码执行、未授权数据外泄、核心安全控制绕过
421
+ - **高** (7.0–8.9):本地权限提升、重大数据完整性破坏、高影响 DoS
422
+ - **中** (4.0–6.9):特定条件下的信息泄露、部分控制绕过
423
+ - **低** (0.1–3.9):轻微信息泄露、纵深防御改进
424
+
425
+ ---
426
+
427
+ ## 安全设计原则
428
+
429
+ ### 1. 本地优先,零网络
430
+
431
+ - 所有 embedding、rerank、记忆整理均在本地运行
432
+ - 记忆文本**永不**离开设备
433
+ - 无遥测、无分析、无远程日志
434
+
435
+ ### 2. 默认 Fail-Safe
436
+
437
+ - 任何组件故障(LLM、embedder、reranker)均优雅降级到关键词搜索
438
+ - 畸形输入不会导致插件崩溃或数据库损坏
439
+ - 并发写入冲突通过 CAS(比较并交换)守卫解决
440
+
441
+ ### 3. 全面审计
442
+
443
+ - 每次 `autoDream` 运行生成密码学可验证的 receipt
444
+ - 每次记忆更新创建 `failure_memories` 审计轨迹
445
+ - 每次搜索记录 `recall_run` 供后续检查
446
+
447
+ ### 4. 人类主权
448
+
449
+ - 所有记忆镜像到人类可编辑的 Markdown 文件
450
+ - 机器写入 vs 人工编辑通过 digest 基线区分
451
+ - 用户可仅凭 Markdown 镜像完整重建数据库
452
+
453
+ ### 5. 最小远程暴露面
454
+
455
+ - 远程 API 端点为可选:需配置 `apiToken` 才生效
456
+ - 配置 token 后,每个远程请求均经过 timing-safe 比较
457
+ - 未配置 token 时,远程端点实际处于禁用状态,所有处理均在本地
458
+
459
+ ---
460
+
461
+ ## 依赖漏洞处理
462
+
463
+ ### 处理流程
464
+
465
+ 我们采用 5 步流程处理第三方依赖漏洞:
466
+
467
+ | 步骤 | 行动 | 时间要求 | 工具 |
468
+ |---|---|---|---|
469
+ | 1. 扫描 | 对所有运行时和开发依赖进行持续自动扫描 | 自动(每日) | OrbisAI Security、npm audit |
470
+ | 2. 评估 | 对每个检测到的漏洞评估严重程度、可利用性和对 dsh-mneme 的影响 | 检测后 48 小时内 | CVSS v3.1、人工代码分析 |
471
+ | 3. 上报 | 将发现记录到安全追踪器,并上报给维护者 | 评估后立即 | 安全追踪器、维护者通道 |
472
+ | 4. 修复 | 升级依赖至已修复版本或应用缓解措施 | 严重:≤ 14 天;高:≤ 30 天;中/低:下个版本 | npm/pnpm 更新、手动补丁 |
473
+ | 5. 披露 | 发布包含详情和已修复版本的安全公告 | 修复版本发布时 | GitHub Security Advisories + npm 发布说明 |
474
+
475
+ ### 第三方依赖政策
476
+
477
+ - 所有新增运行时依赖需通过安全审查后方可引入
478
+ - 存在已知严重漏洞且在期限内无法修复的依赖将被替换为替代方案
479
+ - 依赖锁文件(`package-lock.json`)已提交并在 PR 中审查
480
+
481
+ ### 近期依赖修复
482
+
483
+ | CVE | 包 | 修复前版本 | 修复后版本 | 严重程度 | 修复版本 |
484
+ |---|---|---|---|---|---|
485
+ | CVE-2026-39244 | `adm-zip` | 0.5.18 | 0.6.0 | 高 | v0.3.4 |
486
+
487
+ ---
488
+
489
+ ## 安全审计历史
490
+
491
+ ### v0.2.10 — 安全加固
492
+
493
+ | ID | 发现 | 严重程度 | 状态 |
494
+ |---|---|---|---|
495
+ | F-NEW-01 | `store.js` 并发写入竞态 | **严重** | ✅ 已修复(CAS 守卫 + 原子写入) |
496
+ | F-NEW-02 | 镜像同步期间事务不一致 | **高** | ✅ 已修复(事务化镜像 + 回滚) |
497
+ | F-NEW-03 | 覆盖前未验证镜像健康状态 | **高** | ✅ 已修复(digest 基线 + FSM 验证) |
498
+
499
+ ### v0.3.4 — 依赖安全
500
+
501
+ | CVE | 包 | 严重程度 | 状态 |
502
+ |---|---|---|---|
503
+ | CVE-2026-39244 | `adm-zip` 0.5.18 | **高** | ✅ 已修复(升级至 0.6.0) |
504
+
505
+ ### v0.3.6 — Mirror 债务建模(审计 peer 复核修复)
506
+
507
+ | 发现 | 严重程度 | 状态 |
508
+ |---|---|---|
509
+ | 镜像同步未绑定 generation 计数器(过期覆盖窗口) | **高** | ✅ 已修复(generation + CAS/fence 语义,per-type 状态) |
510
+ | `/health` 端点未鉴权且错误码冗长 | **高** | ✅ 已修复(鉴权门控、错误码净化、读取失败 fail-closed `unknown`) |
511
+ | COMMIT-崩溃窗口可能永久跳过镜像修复 | **高** | ✅ 已修复(dirty 或 generation > applied 时触发 recoverMirror) |
512
+
513
+ ### v0.3.8 — Mirror 同步可靠性(peer 6 blockers)
514
+
515
+ | 发现 | 严重程度 | 状态 |
516
+ |---|---|---|
517
+ | 镜像同步静默失败(错误未上抛至写路径) | **高** | ✅ 已修复(`syncMirror` 返回 `{success, error}`;写入口 `afterSync` 检查) |
518
+ | 多进程并发下 generation 非原子递增 | **高** | ✅ 已修复(`UPDATE ... RETURNING` 原子语句 + `PRAGMA busy_timeout=5000`) |
519
+ | generation 溢出 / 负值 | **中** | ✅ 已修复(JS 校验 + SQL `CHECK(0..MAX_SAFE_INTEGER)`) |
520
+
521
+ ### v0.3.9 — 审计 A/B/D/F
522
+
523
+ | 发现 | 严重程度 | 状态 |
524
+ |---|---|---|
525
+ | CAS 更新与 generation 递增不在同一事务 | **高** | ✅ 已修复(`runAtomically` 原子执行;miss 不递增) |
526
+ | 失败更新可能虚报成功 | **高** | ✅ 已修复(degraded/pending 回执,带 mirror 属性) |
527
+ | generation 校验未 fail-closed | **中** | ✅ 已修复(`Number.isInteger` fail-closed + 迁移检测旧脏值) |
528
+
529
+ ### v0.5.1 — 热记忆负参数防御
530
+
531
+ | 发现 | 严重程度 | 状态 |
532
+ |---|---|---|
533
+ | 负 / 非有限 `maxRounds`/`maxTokens` 可经公开 API 触发同步死循环 | **高** | ✅ 已修复(回退安全默认值 5/2000) |
534
+ | 混合融合分数可超过 1.0(向量 + BM25 叠加) | **中** | ✅ 已修复(钳制到 [0, 1]) |
535
+
536
+ ### v0.6.5 — Tag 系统加固
537
+
538
+ | 发现 | 严重程度 | 状态 |
539
+ |---|---|---|
540
+ | `autoTag` 可能给已遗忘记忆打标签 | **中** | ✅ 已修复(打标前过滤 `forgotten`) |
541
+ | Tag 规范化绕过 sanitizer | **中** | ✅ 已修复(`normalizeTags` 复用 `sanitize`) |
542
+ | `setMemoryTags` 失败时非原子 | **中** | ✅ 已修复(SAVEPOINT 回滚) |
543
+
544
+ ### 持续进行
545
+
546
+ - 通过 **OrbisAI Security** 进行自动化依赖扫描
547
+ - 欢迎社区通过私有公告提交安全审查
548
+
549
+ ---
550
+
551
+ ## 安全公告渠道
552
+
553
+ 安全公告通过以下渠道同时发布:
554
+
555
+ 1. **[GitHub Security Advisories](https://github.com/modusensus/dsh-mneme/security/advisories)** — 主要渠道,包含详细技术信息
556
+ 2. **[npm Releases](https://www.npmjs.com/package/@modusensus/dsh-mneme)** — 发布说明中包含安全公告和修复摘要
557
+
558
+ 接收安全通知方式:
559
+ - **GitHub**:Watch 仓库并在仓库设置中启用“安全警报”
560
+ - **npm**:订阅 `@modusensus/dsh-mneme` 的发布通知
561
+
562
+ ---
563
+
564
+ ## 披露政策
565
+
566
+ 我们实行**协调披露**:
567
+
568
+ 1. 报告者私下提交漏洞
569
+ 2. 我们在 48 小时内确认收到
570
+ 3. 我们开发修复并准备公告(时间取决于严重程度)
571
+ 4. 我们通知报告者修复时间线和计划披露日期
572
+ 5. 我们同时发布补丁和安全公告
573
+ 6. 我们在公告中致谢报告者(经其同意)
574
+
575
+ 我们**不会**对以下安全研究人员采取法律行动:
576
+ - 出于善意行事
577
+ - 不将漏洞利用超出概念验证范围
578
+ - 不访问属于他人的数据
579
+ - 在公开披露前给予我们合理的响应时间
580
+
581
+ **漏洞赏金政策**:本项目目前不提供经济奖励。我们会在公告中公开致谢报告者(经其同意)。
582
+
583
+ ---
584
+
585
+ ## 安全日志与数据保留
586
+
587
+ 所有审计数据**本地**存储于插件数据库,不离开设备:
588
+
589
+ | 数据类型 | 存储位置 | 说明 |
590
+ |---|---|---|
591
+ | `failure_memories` 审计日志 | 本地数据库 | 每次写入失败均记录,供取证分析 |
592
+ | `recall_run` 搜索日志 | 本地数据库 | 每次搜索均记录时间戳和查询元数据 |
593
+ | AutoDream receipts | 本地数据库 + Markdown 镜像 | 密码学可验证;保留至用户删除 |
594
+ | 依赖扫描报告 | OrbisAI Security 控制台 | 不存储于设备 |
595
+
596
+ 保留期由用户控制:审计记录仅随本地数据库存续。无远程日志、无遥测。
597
+
598
+ ---
599
+
600
+ ## 安全相关配置
601
+
602
+ ```yaml
603
+ # 加固配置示例(键均对应 src/config.js 实际配置,除注明外)
604
+ dsh-mneme:
605
+ # 如需完全手动控制,可禁用 autoDream
606
+ autoDream: false
607
+
608
+ # 敏感环境启用冲突冻结
609
+ conflictFreezeEnabled: true
610
+
611
+ # 仅使用本地 embedding(无网络)
612
+ embedProvider: local
613
+
614
+ # 远程端点需 Authorization: Bearer <apiToken>(timing-safe)
615
+ apiToken: "set-a-strong-unique-token"
616
+
617
+ # 提升以将先前的 dream_runs 降级为历史证据
618
+ policyEpoch: 1
619
+
620
+ # 实体抽取默认关闭(数据最小化)
621
+ entityExtractionEnabled: false
622
+
623
+ # Rerank 为 opt-in(默认关闭)——未启用时不下载额外模型
624
+ rerankEnabled: false
625
+
626
+ # 自动打标签默认关闭(数据最小化)
627
+ autoTagEnabled: false
628
+
629
+ # 不需要会话级清理时可关闭会话生命周期
630
+ sessionLifecycleEnabled: false
631
+
632
+ # 不需要后台维护时可关闭 Sleep Mode
633
+ sleepModeEnabled: false
634
+
635
+ # 记忆可信度加权为 opt-in(默认关闭)
636
+ trustEpistemicWeighting: false
637
+
638
+ # LLM 审计日志保留天数
639
+ llmAudit:
640
+ enabled: true
641
+ retentionDays: 90
642
+ ```
643
+
644
+ ---
645
+
646
+ ## 贡献者安全指南
647
+
648
+ 所有贡献者必须遵守以下安全要求:
649
+
650
+ 1. **依赖审计**:提交 PR 前运行 `npm audit`;新增依赖必须通过安全审查
651
+ 2. **密钥扫描**:禁止向仓库提交 API 密钥、令牌或凭据
652
+ 3. **输入验证**:所有用户输入必须验证和净化(包括 LLM 相关内容)
653
+ 4. **安全代码审查**:涉及安全相关变更的 PR 需获得具有安全专业知识维护者的批准
654
+ 5. **文档记录**:新功能必须在 PR 描述中包含安全影响分析
655
+ 6. **负责任的披露**:开发过程中发现的安全漏洞必须通过适当渠道报告,而非在公开 PR 中提交
656
+
657
+ ---
658
+
659
+ ## 联系方式
660
+
661
+ - **安全团队**:`guanqishi26@gmail.com`
662
+ - **私有公告**:[GitHub Security Advisories](https://github.com/modusensus/dsh-mneme/security/advisories)
663
+ - **GPG 密钥**:如需加密通信,可应请求提供
664
+
665
+ ---
666
+
667
+ ## 许可协议
668
+
669
+ 本项目基于 **MIT License** 开源。详见 [LICENSE](https://github.com/modusensus/dsh-mneme/blob/main/LICENSE)。
670
+
671
+ ---
672
+
673
+ *Last updated: 2026-08-28*
674
+ *Policy version: 2.2*