@wipcomputer/memory-crystal 0.7.32 → 0.7.34-alpha.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 (155) hide show
  1. package/SKILL.md +1 -1
  2. package/cloud/wrangler.toml +30 -0
  3. package/dist/bridge.d.ts +7 -0
  4. package/dist/bridge.js +14 -0
  5. package/dist/bulk-copy.d.ts +17 -0
  6. package/dist/bulk-copy.js +90 -0
  7. package/dist/cc-hook.d.ts +8 -0
  8. package/dist/cc-hook.js +368 -0
  9. package/dist/cc-poller.d.ts +1 -0
  10. package/dist/cc-poller.js +550 -0
  11. package/dist/chunk-25LXQJ4Z.js +110 -0
  12. package/dist/chunk-2DRXIRQW.js +97 -0
  13. package/dist/chunk-2GBYLMEF.js +1385 -0
  14. package/dist/chunk-2ZNH5F6E.js +1281 -0
  15. package/dist/chunk-3G3SFYYI.js +288 -0
  16. package/dist/chunk-3RG5ZIWI.js +10 -0
  17. package/dist/chunk-3S6TI23B.js +97 -0
  18. package/dist/chunk-3VFIJYS4.js +818 -0
  19. package/dist/chunk-437F27T6.js +97 -0
  20. package/dist/chunk-52QE3YI3.js +1169 -0
  21. package/dist/chunk-57RP3DIN.js +1205 -0
  22. package/dist/chunk-5HSZ4W2P.js +62 -0
  23. package/dist/chunk-5I7GMRDN.js +146 -0
  24. package/dist/chunk-645IPXW3.js +290 -0
  25. package/dist/chunk-7A7ELD4C.js +1205 -0
  26. package/dist/chunk-7FYY4GZM.js +1205 -0
  27. package/dist/chunk-7IUE7ODU.js +254 -0
  28. package/dist/chunk-7RMLKZIS.js +108 -0
  29. package/dist/chunk-AA3OPP4Z.js +432 -0
  30. package/dist/chunk-AEWLSYPH.js +72 -0
  31. package/dist/chunk-ASSZDR6I.js +108 -0
  32. package/dist/chunk-AYRJVWUC.js +1205 -0
  33. package/dist/chunk-CCYI5O3D.js +148 -0
  34. package/dist/chunk-CGIDSAJB.js +288 -0
  35. package/dist/chunk-D3I3ZSE2.js +411 -0
  36. package/dist/chunk-D3MACYZ4.js +108 -0
  37. package/dist/chunk-DACSKLY6.js +219 -0
  38. package/dist/chunk-DFQ72B7M.js +248 -0
  39. package/dist/chunk-DW5B4BL7.js +108 -0
  40. package/dist/chunk-EKSACBTJ.js +1070 -0
  41. package/dist/chunk-EXEZZADG.js +248 -0
  42. package/dist/chunk-F3Y7EL7K.js +83 -0
  43. package/dist/chunk-FBQWSDPC.js +1328 -0
  44. package/dist/chunk-FHRZNOMW.js +1205 -0
  45. package/dist/chunk-IM7N24MT.js +129 -0
  46. package/dist/chunk-IPNYIXFK.js +1178 -0
  47. package/dist/chunk-J7MRSZIO.js +167 -0
  48. package/dist/chunk-JITKI2OI.js +106 -0
  49. package/dist/chunk-JWZXYVET.js +1068 -0
  50. package/dist/chunk-KCQUXVYT.js +108 -0
  51. package/dist/chunk-KOQ43OX6.js +1281 -0
  52. package/dist/chunk-KYVWO6ZM.js +1069 -0
  53. package/dist/chunk-L3VHARQH.js +413 -0
  54. package/dist/chunk-LBWDS6BE.js +288 -0
  55. package/dist/chunk-LOVAHSQV.js +411 -0
  56. package/dist/chunk-LQOYCAGG.js +446 -0
  57. package/dist/chunk-LWAIPJ2W.js +146 -0
  58. package/dist/chunk-M5DHKW7M.js +127 -0
  59. package/dist/chunk-MBKCIJHM.js +1328 -0
  60. package/dist/chunk-MK42FMEG.js +147 -0
  61. package/dist/chunk-MOBMYHKL.js +1205 -0
  62. package/dist/chunk-MPLTNMRG.js +67 -0
  63. package/dist/chunk-NIJCVN3O.js +147 -0
  64. package/dist/chunk-NX647OM3.js +310 -0
  65. package/dist/chunk-NZCFSZQ7.js +1205 -0
  66. package/dist/chunk-O2UITJGH.js +465 -0
  67. package/dist/chunk-OCRA44AZ.js +108 -0
  68. package/dist/chunk-P3KJR66H.js +117 -0
  69. package/dist/chunk-PEK6JH65.js +432 -0
  70. package/dist/chunk-PJ6FFKEX.js +77 -0
  71. package/dist/chunk-PLUBBZYR.js +800 -0
  72. package/dist/chunk-PNKVD2UK.js +26 -0
  73. package/dist/chunk-PSQZURHO.js +229 -0
  74. package/dist/chunk-SGL6ISBJ.js +1061 -0
  75. package/dist/chunk-SJABZZT5.js +97 -0
  76. package/dist/chunk-TD3P3K32.js +1199 -0
  77. package/dist/chunk-TMDZJJKV.js +288 -0
  78. package/dist/chunk-UNHVZB5G.js +411 -0
  79. package/dist/chunk-VAFTWSTE.js +1061 -0
  80. package/dist/chunk-VNFXFQBB.js +217 -0
  81. package/dist/chunk-X3GVFKSJ.js +1205 -0
  82. package/dist/chunk-XZ3S56RQ.js +1061 -0
  83. package/dist/chunk-Y72C7F6O.js +148 -0
  84. package/dist/chunk-YLICP577.js +1205 -0
  85. package/dist/chunk-YX6AXLVK.js +159 -0
  86. package/dist/chunk-ZCQYHTNU.js +146 -0
  87. package/dist/cli.d.ts +1 -0
  88. package/dist/cli.js +1160 -0
  89. package/dist/cloud-crystal.js +6 -0
  90. package/dist/core.d.ts +252 -0
  91. package/dist/core.js +12 -0
  92. package/dist/crypto.d.ts +20 -0
  93. package/dist/crypto.js +27 -0
  94. package/dist/crystal-capture.sh +29 -0
  95. package/dist/crystal-serve.d.ts +4 -0
  96. package/dist/crystal-serve.js +252 -0
  97. package/dist/dev-update-SZ2Z4WCQ.js +6 -0
  98. package/dist/discover.d.ts +30 -0
  99. package/dist/discover.js +177 -0
  100. package/dist/doctor.d.ts +9 -0
  101. package/dist/doctor.js +342 -0
  102. package/dist/dream-weaver.d.ts +8 -0
  103. package/dist/dream-weaver.js +56 -0
  104. package/dist/file-sync.d.ts +48 -0
  105. package/dist/file-sync.js +18 -0
  106. package/dist/installer.d.ts +61 -0
  107. package/dist/installer.js +772 -0
  108. package/dist/ldm-backup.sh +116 -0
  109. package/dist/ldm.d.ts +50 -0
  110. package/dist/ldm.js +32 -0
  111. package/dist/llm-XXLYPIOF.js +16 -0
  112. package/dist/mcp-server.d.ts +1 -0
  113. package/dist/mcp-server.js +277 -0
  114. package/dist/migrate.d.ts +1 -0
  115. package/dist/migrate.js +89 -0
  116. package/dist/mirror-sync.d.ts +1 -0
  117. package/dist/mirror-sync.js +159 -0
  118. package/dist/mlx-setup-XKU67WCT.js +289 -0
  119. package/dist/oc-backfill.d.ts +19 -0
  120. package/dist/oc-backfill.js +74 -0
  121. package/dist/openclaw.d.ts +5 -0
  122. package/dist/openclaw.js +434 -0
  123. package/dist/pair.d.ts +4 -0
  124. package/dist/pair.js +75 -0
  125. package/dist/poller.d.ts +1 -0
  126. package/dist/poller.js +634 -0
  127. package/dist/role.d.ts +24 -0
  128. package/dist/role.js +13 -0
  129. package/dist/search-pipeline-4K4OJSSS.js +255 -0
  130. package/dist/search-pipeline-4PRS6LI7.js +280 -0
  131. package/dist/search-pipeline-7UJMXPLO.js +280 -0
  132. package/dist/search-pipeline-CBV25NX7.js +99 -0
  133. package/dist/search-pipeline-DQTRLGBH.js +74 -0
  134. package/dist/search-pipeline-HNG37REH.js +282 -0
  135. package/dist/search-pipeline-IZFPLBUB.js +280 -0
  136. package/dist/search-pipeline-MID6F26Q.js +73 -0
  137. package/dist/search-pipeline-N52JZFNN.js +282 -0
  138. package/dist/search-pipeline-OPB2PRQQ.js +280 -0
  139. package/dist/search-pipeline-VXTE5HAD.js +262 -0
  140. package/dist/search-pipeline-XHFKADRG.js +73 -0
  141. package/dist/staging.d.ts +29 -0
  142. package/dist/staging.js +21 -0
  143. package/dist/summarize.d.ts +19 -0
  144. package/dist/summarize.js +10 -0
  145. package/dist/worker-demo.js +186 -0
  146. package/dist/worker-mcp.js +404 -0
  147. package/dist/worker.js +137 -0
  148. package/package.json +15 -1
  149. package/.env.example +0 -20
  150. package/.publish-skill.json +0 -1
  151. package/CHANGELOG.md +0 -1372
  152. package/README-ENTERPRISE.md +0 -226
  153. package/RELAY.md +0 -199
  154. package/wrangler-demo.toml +0 -8
  155. package/wrangler-mcp.toml +0 -24
package/CHANGELOG.md DELETED
@@ -1,1372 +0,0 @@
1
- # Changelog
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
- ## 0.7.32 (2026-03-31)
23
-
24
- # Release Notes: memory-crystal v0.7.32
25
-
26
- **Date:** 2026-03-31
27
-
28
- ## What changed
29
-
30
- ### Dream Weaver is a required dependency again
31
-
32
- Reverts PR #101 (optional Dream Weaver import). dream-weaver-protocol is back in `dependencies` instead of `optionalDependencies`. The static import in `dream-weaver.ts` is restored. The dynamic import with try/catch wrapper is removed. The null check in `cli.ts` for when DW is unavailable is removed.
33
-
34
- ## Why
35
-
36
- PR #101 made dream-weaver-protocol optional because `file:../dream-weaver-protocol-private` failed in fresh clones where the sibling directory doesn't exist. The installer (v0.4.68+) now resolves `file:` dependencies from installed extensions at `~/.ldm/extensions/` before building, so the sibling directory is no longer needed. The build succeeds without it.
37
-
38
- Making DW optional added complexity (dynamic imports, null checks, degraded type safety) that is no longer necessary. This revert simplifies the code back to what it was.
39
-
40
- ## How to verify
41
-
42
- ```bash
43
- # Build should succeed (installer resolves file: deps)
44
- cd memory-crystal-private && npm run build
45
-
46
- # dream-weaver-protocol should be in dependencies, not optionalDependencies
47
- node -e "const p = require('./package.json'); console.log('deps:', !!p.dependencies['dream-weaver-protocol']); console.log('optional:', !!p.optionalDependencies?.['dream-weaver-protocol'])"
48
- # Should print: deps: true, optional: false
49
- ```
50
-
51
- ## 0.7.31 (2026-03-31)
52
-
53
- # Release Notes: memory-crystal v0.7.31
54
-
55
- Closes #101
56
-
57
- ## Dream Weaver protocol is now optional
58
-
59
- The dream-weaver-protocol dependency was a `file:` reference to a sibling directory. This worked in the development environment but broke when the installer cloned the repo to build (the sibling doesn't exist in a clone context). The build failed with "Cannot find module 'dream-weaver-protocol'".
60
-
61
- The protocol is now an optional dependency with a dynamic import. If dream-weaver-protocol is available (installed locally or linked), Dream Weaver features work normally. If not, crystal operations continue without Dream Weaver. The build succeeds either way.
62
-
63
- This is part of a broader fix to make all repos buildable in isolation. The installer (v0.4.67+) now resolves `file:` dependencies from installed extensions before building, so the protocol will be linked automatically when both packages are installed.
64
-
65
- ## 0.7.30 (2026-03-31)
66
-
67
- # Release Notes: memory-crystal v0.7.30
68
-
69
- **Date:** 2026-03-30
70
-
71
- ## What changed
72
-
73
- ### Hardcoded path removal
74
-
75
- Two files had `/Users/lesa` hardcoded as a fallback path. Both now use portable alternatives.
76
-
77
- **migrate-lance-to-sqlite.mjs** had a fallback that resolved the OpenClaw workspace to `/Users/lesa/.openclaw`. The migration script now calls `os.homedir()` to build the path dynamically, so it works on any machine without assuming a specific username. This was the last remaining hardcoded path in the migration pipeline (#99).
78
-
79
- **dev-update.ts** (the ai/dev-updates scanner) had an iCloud path baked in for reading team documents. It now calls `resolveWorkspace()` to read the workspace root from LDM config (`~/.ldm/config.json`), making it portable across machines and user accounts (#98).
80
-
81
- ## Why
82
-
83
- These paths broke on any machine where the username is not `lesa`. Part of a broader audit across all LDM OS repos to eliminate hardcoded user paths and make everything portable.
84
-
85
- ## Issues closed
86
-
87
- - #98
88
- - #99
89
-
90
- ## How to verify
91
-
92
- ```bash
93
- grep -r "/Users/lesa" src/ scripts/ --include="*.ts" --include="*.mjs"
94
- # Should return zero results
95
- ```
96
-
97
- ## 0.7.29 (2026-03-20)
98
-
99
- # Release Notes: memory-crystal v0.7.29
100
-
101
- **Doc audit: MLX setup, deep search params, log paths, role clarification.**
102
-
103
- ## What changed
104
-
105
- SKILL.md and TECHNICAL.md updated for 2 weeks of undocumented features:
106
-
107
- - **MLX local LLM:** Added as Option A in SKILL.md Step 2. CLI commands (setup, status, stop) added to TECHNICAL.md.
108
- - **Deep search parameters:** `--intent`, `--explain`, `--candidates` documented in both SKILL.md (crystal_search tool) and TECHNICAL.md (CLI reference + new sections for intent, explain, candidate limit, LLM cache).
109
- - **Log paths:** Fixed obsolete `/tmp/ldm-dev-tools/` reference to `~/.ldm/logs/`. Added logs/ to directory structure.
110
- - **Role clarification:** Two-role architecture (Core and Node) explicitly stated. Standalone role was removed in v0.7.22.
111
-
112
- ## Why
113
-
114
- 29 releases in 13 days. Docs didn't keep pace. Agents using crystal_search didn't know about --intent (query disambiguation) or --explain (scoring transparency).
115
-
116
- ## Issues closed
117
-
118
- - #57
119
-
120
- ## How to verify
121
-
122
- ```bash
123
- grep "intent" SKILL.md TECHNICAL.md
124
- grep "mlx" SKILL.md TECHNICAL.md
125
- grep "ldm/logs" TECHNICAL.md
126
- ```
127
-
128
- ## 0.7.28 (2026-03-18)
129
-
130
- # Release Notes: memory-crystal v0.7.28
131
-
132
- **One-line summary of what this release does**
133
-
134
- ## What changed
135
-
136
- Describe the changes. Not a commit list. Explain:
137
- - What was built or fixed
138
- - Why it matters
139
- - What the user should know
140
-
141
- ## Why
142
-
143
- What problem does this solve? What was broken or missing?
144
-
145
- ## Issues closed
146
-
147
- - #91
148
-
149
- ## How to verify
150
-
151
- ```bash
152
- # Commands to test the changes
153
- ```
154
-
155
- ## 0.7.27 (2026-03-17)
156
-
157
- # Add root SKILL.md + ldm install as primary path
158
-
159
- Added SKILL.md to repo root (source of truth for wip-release website publishing). `ldm install wipcomputer/memory-crystal` is now the recommended install path. `crystal init` stays for MC-specific setup (database, cron, role, pairing).
160
-
161
- Also added `.publish-skill.json` so wip-release publishes SKILL.md to wip.computer/install/.
162
-
163
- Closes wipcomputer/wip-ldm-os#97. Convergence tracked in wipcomputer/wip-ldm-os#99.
164
-
165
- ## 0.7.26 (2026-03-16)
166
-
167
- # Memory Crystal v0.7.26
168
-
169
- Add repository field to package.json. GitHub Packages needs this to link packages to the repo.
170
-
171
- ## Issues closed
172
-
173
- - Closes #50
174
-
175
- ## 0.7.25 (2026-03-16)
176
-
177
- # Release Notes: memory-crystal v0.7.25
178
-
179
- Bump SKILL.md version and name to match package branding.
180
-
181
- ## What changed
182
-
183
- - SKILL.md version bumped from 0.4.0 to 0.7.24 (was stuck at the original version)
184
- - SKILL.md name changed from `memory` to `wip-memory-crystal` (matches branded convention)
185
- - Forces deploy to public repo, triggering auto-publish to wip.computer/install/
186
-
187
- ## Why
188
-
189
- The SKILL.md version was out of sync with the package version. The name didn't match the `wip-` branding convention used across all install files on wip.computer.
190
-
191
- ## Issues closed
192
-
193
- - #80
194
-
195
- ## How to verify
196
-
197
- ```bash
198
- crystal --version
199
- head -4 ~/.ldm/extensions/memory-crystal/skills/memory/SKILL.md
200
- ```
201
-
202
- ## 0.7.24 (2026-03-15)
203
-
204
- # Dev Update: Search Quality v2 + MLX Local LLM
205
-
206
- **Date:** 2026-03-15
207
- **Author:** CC-Mini
208
- **Session:** memory-crstal01 (continued from Mar 13-14)
209
-
210
- ---
211
-
212
- ## Summary
213
-
214
- Six search quality features from QMD v2.0 analysis, plus MLX local LLM infrastructure for Apple Silicon. All coded, tested, merged. Not yet deployed.
215
-
216
- ## What Shipped
217
-
218
- ### Search Quality (PR #75)
219
-
220
- 1. **Intent parameter.** Disambiguates queries without adding search terms. `crystal search "security" --intent "1Password"` steers toward 1Password results. Flows through expansion prompt (guides LLM variations), disables strong-signal bypass, prepended to rerank query. Available via CLI `--intent`, MCP `intent`.
221
-
222
- 2. **candidateLimit.** Tunable rerank pool size. `crystal search "query" --candidates 60`. Default stays 40. More candidates = better recall, slower reranking. Available via CLI `--candidates`, MCP `candidate_limit`.
223
-
224
- 3. **Explain mode.** Per-result scoring breakdown showing FTS score, vector score, RRF rank, reranker score, recency weight, and final blended score. `crystal search "query" --explain`. Available via CLI `--explain`, MCP `explain`.
225
-
226
- 4. **Persistent LLM cache.** `llm_cache` table in crystal.db. Expansion and reranking results cached with 7-day TTL. Content-addressable reranking (keyed by query + sorted passage hashes). Same query = instant on repeat searches. Configurable TTL via `CRYSTAL_CACHE_TTL_DAYS`.
227
-
228
- 5. **Structured search API.** `crystal.structuredSearch(queries)` accepts pre-expanded StructuredQuery[] (lex, vec, hyde). Skips LLM expansion entirely. Agents construct their own queries when they know what they want. RRF fusion with first list weighted 2x.
229
-
230
- ### MLX Local LLM (PR #76)
231
-
232
- 6. **MLX auto-install.** New `src/mlx-setup.ts` with full setup flow:
233
- - `detectPlatform()` ... Apple Silicon / Intel Mac / Linux / other
234
- - `installMlxLm()` ... uv > pip3 > pip3 --user fallback chain
235
- - `createLaunchAgent()` ... always-on MLX server via LaunchAgent
236
- - `verifyServer()` ... 30s warmup wait for model loading
237
- - `setupMlx()` ... full flow: detect, install, configure, start, verify
238
-
239
- 7. **Crystal MLX CLI.** `crystal mlx setup/status/stop` subcommands.
240
-
241
- 8. **Doctor check #13.** MLX health check with three states: not installed, installed but not running, running. Suggests fix for each.
242
-
243
- 9. **Installer integration.** `crystal init` detects Apple Silicon and suggests `crystal mlx setup` when MLX is not installed.
244
-
245
- 10. **Port 18791.** LDM service ports: 18789 (OpenClaw), 18790 (Crystal Core), 18791 (MLX LLM).
246
-
247
- 11. **Model: Qwen 2.5 3B Instruct 4-bit.** `mlx-community/Qwen2.5-3B-Instruct-4bit`. ~1.5 GB, fast on M-series, good at instruction following for query expansion and relevance scoring.
248
-
249
- ### Also
250
-
251
- - QMD v2.0 analysis written (`ai/product/notes/2026-03-15--cc-mini--qmd-v2.0-analysis.md`)
252
- - Search quality plan written (`ai/product/plans-prds/current/2026-03-15--cc-mini--search-quality-qmd-v2-port.md`)
253
- - MLX plan moved from upcoming to current
254
- - Stashed roadmap + readme-first updates recovered and committed (PR #74)
255
- - README footer: QMD credit restored, CLA + dual license confirmed on both repos
256
-
257
- ## Files Changed
258
-
259
- | File | Change |
260
- |------|--------|
261
- | `src/search-pipeline.ts` | Intent support, candidateLimit param, explain traces, DeepSearchResult type |
262
- | `src/llm.ts` | Intent in expansion prompt, persistent DB cache (expansion + reranking), setLLMCacheDb() |
263
- | `src/core.ts` | llm_cache table schema, deepSearch options, structuredSearch() method, StructuredQuery type |
264
- | `src/mcp-server.ts` | intent, candidate_limit, explain params on crystal_search, LLM cache DB wiring |
265
- | `src/cli.ts` | --intent, --candidates, --explain flags, crystal mlx subcommand |
266
- | `src/mlx-setup.ts` | **NEW** ... full MLX setup, doctor check, state management |
267
- | `src/doctor.ts` | MLX health check (#13) |
268
- | `src/installer.ts` | MLX detection in crystal init flow |
269
-
270
- ## What This Enables
271
-
272
- - **Free deep search.** MLX replaces OpenAI API calls for expansion + reranking. Zero cost per search.
273
- - **Faster repeated searches.** Persistent cache means the LLM call happens once per unique query.
274
- - **Smarter agent queries.** Structured search lets agents skip expansion when they know what they want.
275
- - **Debuggable search.** Explain mode shows exactly why each result ranked where it did.
276
- - **Offline search quality.** MLX works without internet. API fallback when MLX is down.
277
-
278
- ## 0.7.23 (2026-03-15)
279
-
280
- # Release Notes: Memory Crystal v0.7.23
281
-
282
- **Date:** 2026-03-15
283
-
284
- ## Search Quality v2 + MLX Local LLM
285
-
286
- This release adds six search quality features ported from the QMD v2.0 analysis, plus the complete MLX local LLM infrastructure for Apple Silicon. Deep search is now disambiguatable, cacheable, debuggable, and can run entirely offline on Apple Silicon.
287
-
288
- ### Intent parameter
289
-
290
- Disambiguates queries without adding search terms. `crystal search "security" --intent "1Password"` steers results toward 1Password-related security instead of repo permissions or agent secrets. Intent flows through the expansion prompt (guides LLM variations), disables strong-signal bypass (keyword match might not be what the caller wants), and is prepended to the rerank query. Available via CLI `--intent` and MCP `intent`.
291
-
292
- ### Persistent LLM cache
293
-
294
- Expansion and reranking results are now cached in crystal.db (`llm_cache` table) with a 7-day TTL. Same query = instant on repeat searches. Reranking cache is content-addressable (keyed by query + sorted passage hashes), so identical content from different sessions shares cached scores. Configurable via `CRYSTAL_CACHE_TTL_DAYS` env var.
295
-
296
- ### Explain mode
297
-
298
- Per-result scoring breakdown showing FTS score, vector score, RRF rank, reranker score, recency weight, and final blended score. `crystal search "query" --explain`. Available via CLI `--explain` and MCP `explain`. Makes search quality transparent and debuggable.
299
-
300
- ### candidateLimit
301
-
302
- Tunable rerank pool size. `crystal search "query" --candidates 60`. Default stays 40. More candidates = better recall, slower reranking. Available via CLI `--candidates` and MCP `candidate_limit`.
303
-
304
- ### Structured search API
305
-
306
- `crystal.structuredSearch(queries)` accepts pre-expanded StructuredQuery[] with typed sub-queries (lex, vec, hyde). Skips LLM expansion entirely. Agents construct their own queries when they already know what they want. RRF fusion with first list weighted 2x.
307
-
308
- ### MLX local LLM (Phase 3)
309
-
310
- Complete auto-install infrastructure for running a local LLM on Apple Silicon:
311
-
312
- - `crystal mlx setup` detects Apple Silicon, installs mlx-lm (uv > pip3 > pip3 --user), creates LaunchAgent for always-on server
313
- - Model: `mlx-community/Qwen2.5-3B-Instruct-4bit` (~1.5 GB, fast on M-series)
314
- - Port 18791 (18789 OpenClaw, 18790 Crystal Core, 18791 MLX)
315
- - `crystal mlx status` and `crystal mlx stop` for server management
316
- - `crystal doctor` check #13: MLX health (not installed / down / running)
317
- - `crystal init` detects Apple Silicon and suggests MLX setup
318
- - State file at `~/.ldm/state/mlx-server.json`
319
-
320
- ### Also in this release
321
-
322
- - QMD v2.0 analysis documented (`ai/product/notes/`)
323
- - Search quality plan written (`ai/product/plans-prds/current/`)
324
- - MLX plan moved from upcoming to current
325
- - Stashed roadmap + readme-first updates recovered (PR #74)
326
-
327
- Closes #57, #63, #64.
328
-
329
- ## 0.7.22 (2026-03-14)
330
-
331
- Remove standalone role
332
-
333
- ## 0.7.21 (2026-03-14)
334
-
335
- Fix install URL
336
-
337
- ## 0.7.20 (2026-03-14)
338
-
339
- Add CLA, dual LICENSE, standardize README footer
340
-
341
- ## 0.7.19 (2026-03-14)
342
-
343
- Fix score normalization
344
-
345
- ## 0.7.18 (2026-03-13)
346
-
347
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
348
-
349
- **Date:** 2026-03-13
350
- **Author:** CC-Mini
351
- **Session:** memory-db-fix
352
-
353
- ---
354
-
355
- ## What Happened
356
-
357
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
358
-
359
- ### Issue 1: Doctor False Positive
360
-
361
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
362
-
363
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
364
-
365
- ### Issue 2: Orphaned Vectors and FTS Entries
366
-
367
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
368
-
369
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
370
-
371
- **Impact:**
372
- - 141,651 orphaned vectors (~875 MB)
373
- - 141,652 orphaned FTS entries
374
- - ~7% of search queries hit phantom results (silently filtered out)
375
- - Database: 1.96 GB (should have been ~1 GB)
376
-
377
- **Fix (three parts):**
378
-
379
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
380
- ```sql
381
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
382
- BEGIN
383
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
384
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
385
- END;
386
- ```
387
-
388
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
389
-
390
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
391
-
392
- **Cleanup results:**
393
- - 141,651 orphaned vectors removed
394
- - FTS rebuilt from 73,813 chunks in 5.7s
395
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
396
- - Verification: chunks = FTS entries = 73,813. Match: YES
397
- - Zero orphans remaining
398
-
399
- ### Side Discovery: Plaintext SA Token
400
-
401
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
402
-
403
- ### Product Rule Established
404
-
405
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
406
-
407
- ## Files Changed
408
-
409
- | File | Change |
410
- |------|--------|
411
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
412
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
413
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
414
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
415
-
416
- ## Related (wip-secrets-ios-private)
417
-
418
- | File | What |
419
- |------|------|
420
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
421
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
422
-
423
- ## Status
424
-
425
- - Code deployed and running (cleanup already executed)
426
- - Not yet committed / PR'd / released
427
- - Needs: branch, commit, PR, merge, `wip-release patch`
428
-
429
- ## 0.7.17 (2026-03-13)
430
-
431
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
432
-
433
- **Date:** 2026-03-13
434
- **Author:** CC-Mini
435
- **Session:** memory-db-fix
436
-
437
- ---
438
-
439
- ## What Happened
440
-
441
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
442
-
443
- ### Issue 1: Doctor False Positive
444
-
445
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
446
-
447
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
448
-
449
- ### Issue 2: Orphaned Vectors and FTS Entries
450
-
451
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
452
-
453
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
454
-
455
- **Impact:**
456
- - 141,651 orphaned vectors (~875 MB)
457
- - 141,652 orphaned FTS entries
458
- - ~7% of search queries hit phantom results (silently filtered out)
459
- - Database: 1.96 GB (should have been ~1 GB)
460
-
461
- **Fix (three parts):**
462
-
463
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
464
- ```sql
465
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
466
- BEGIN
467
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
468
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
469
- END;
470
- ```
471
-
472
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
473
-
474
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
475
-
476
- **Cleanup results:**
477
- - 141,651 orphaned vectors removed
478
- - FTS rebuilt from 73,813 chunks in 5.7s
479
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
480
- - Verification: chunks = FTS entries = 73,813. Match: YES
481
- - Zero orphans remaining
482
-
483
- ### Side Discovery: Plaintext SA Token
484
-
485
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
486
-
487
- ### Product Rule Established
488
-
489
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
490
-
491
- ## Files Changed
492
-
493
- | File | Change |
494
- |------|--------|
495
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
496
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
497
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
498
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
499
-
500
- ## Related (wip-secrets-ios-private)
501
-
502
- | File | What |
503
- |------|------|
504
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
505
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
506
-
507
- ## Status
508
-
509
- - Code deployed and running (cleanup already executed)
510
- - Not yet committed / PR'd / released
511
- - Needs: branch, commit, PR, merge, `wip-release patch`
512
-
513
- ## 0.7.16 (2026-03-13)
514
-
515
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
516
-
517
- **Date:** 2026-03-13
518
- **Author:** CC-Mini
519
- **Session:** memory-db-fix
520
-
521
- ---
522
-
523
- ## What Happened
524
-
525
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
526
-
527
- ### Issue 1: Doctor False Positive
528
-
529
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
530
-
531
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
532
-
533
- ### Issue 2: Orphaned Vectors and FTS Entries
534
-
535
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
536
-
537
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
538
-
539
- **Impact:**
540
- - 141,651 orphaned vectors (~875 MB)
541
- - 141,652 orphaned FTS entries
542
- - ~7% of search queries hit phantom results (silently filtered out)
543
- - Database: 1.96 GB (should have been ~1 GB)
544
-
545
- **Fix (three parts):**
546
-
547
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
548
- ```sql
549
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
550
- BEGIN
551
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
552
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
553
- END;
554
- ```
555
-
556
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
557
-
558
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
559
-
560
- **Cleanup results:**
561
- - 141,651 orphaned vectors removed
562
- - FTS rebuilt from 73,813 chunks in 5.7s
563
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
564
- - Verification: chunks = FTS entries = 73,813. Match: YES
565
- - Zero orphans remaining
566
-
567
- ### Side Discovery: Plaintext SA Token
568
-
569
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
570
-
571
- ### Product Rule Established
572
-
573
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
574
-
575
- ## Files Changed
576
-
577
- | File | Change |
578
- |------|--------|
579
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
580
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
581
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
582
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
583
-
584
- ## Related (wip-secrets-ios-private)
585
-
586
- | File | What |
587
- |------|------|
588
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
589
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
590
-
591
- ## Status
592
-
593
- - Code deployed and running (cleanup already executed)
594
- - Not yet committed / PR'd / released
595
- - Needs: branch, commit, PR, merge, `wip-release patch`
596
-
597
- ## 0.7.15 (2026-03-13)
598
-
599
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
600
-
601
- **Date:** 2026-03-13
602
- **Author:** CC-Mini
603
- **Session:** memory-db-fix
604
-
605
- ---
606
-
607
- ## What Happened
608
-
609
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
610
-
611
- ### Issue 1: Doctor False Positive
612
-
613
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
614
-
615
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
616
-
617
- ### Issue 2: Orphaned Vectors and FTS Entries
618
-
619
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
620
-
621
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
622
-
623
- **Impact:**
624
- - 141,651 orphaned vectors (~875 MB)
625
- - 141,652 orphaned FTS entries
626
- - ~7% of search queries hit phantom results (silently filtered out)
627
- - Database: 1.96 GB (should have been ~1 GB)
628
-
629
- **Fix (three parts):**
630
-
631
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
632
- ```sql
633
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
634
- BEGIN
635
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
636
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
637
- END;
638
- ```
639
-
640
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
641
-
642
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
643
-
644
- **Cleanup results:**
645
- - 141,651 orphaned vectors removed
646
- - FTS rebuilt from 73,813 chunks in 5.7s
647
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
648
- - Verification: chunks = FTS entries = 73,813. Match: YES
649
- - Zero orphans remaining
650
-
651
- ### Side Discovery: Plaintext SA Token
652
-
653
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
654
-
655
- ### Product Rule Established
656
-
657
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
658
-
659
- ## Files Changed
660
-
661
- | File | Change |
662
- |------|--------|
663
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
664
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
665
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
666
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
667
-
668
- ## Related (wip-secrets-ios-private)
669
-
670
- | File | What |
671
- |------|------|
672
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
673
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
674
-
675
- ## Status
676
-
677
- - Code deployed and running (cleanup already executed)
678
- - Not yet committed / PR'd / released
679
- - Needs: branch, commit, PR, merge, `wip-release patch`
680
-
681
- ## 0.7.14 (2026-03-13)
682
-
683
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
684
-
685
- **Date:** 2026-03-13
686
- **Author:** CC-Mini
687
- **Session:** memory-db-fix
688
-
689
- ---
690
-
691
- ## What Happened
692
-
693
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
694
-
695
- ### Issue 1: Doctor False Positive
696
-
697
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
698
-
699
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
700
-
701
- ### Issue 2: Orphaned Vectors and FTS Entries
702
-
703
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
704
-
705
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
706
-
707
- **Impact:**
708
- - 141,651 orphaned vectors (~875 MB)
709
- - 141,652 orphaned FTS entries
710
- - ~7% of search queries hit phantom results (silently filtered out)
711
- - Database: 1.96 GB (should have been ~1 GB)
712
-
713
- **Fix (three parts):**
714
-
715
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
716
- ```sql
717
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
718
- BEGIN
719
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
720
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
721
- END;
722
- ```
723
-
724
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
725
-
726
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
727
-
728
- **Cleanup results:**
729
- - 141,651 orphaned vectors removed
730
- - FTS rebuilt from 73,813 chunks in 5.7s
731
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
732
- - Verification: chunks = FTS entries = 73,813. Match: YES
733
- - Zero orphans remaining
734
-
735
- ### Side Discovery: Plaintext SA Token
736
-
737
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
738
-
739
- ### Product Rule Established
740
-
741
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
742
-
743
- ## Files Changed
744
-
745
- | File | Change |
746
- |------|--------|
747
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
748
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
749
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
750
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
751
-
752
- ## Related (wip-secrets-ios-private)
753
-
754
- | File | What |
755
- |------|------|
756
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
757
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
758
-
759
- ## Status
760
-
761
- - Code deployed and running (cleanup already executed)
762
- - Not yet committed / PR'd / released
763
- - Needs: branch, commit, PR, merge, `wip-release patch`
764
-
765
- ## 0.7.13 (2026-03-13)
766
-
767
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
768
-
769
- **Date:** 2026-03-13
770
- **Author:** CC-Mini
771
- **Session:** memory-db-fix
772
-
773
- ---
774
-
775
- ## What Happened
776
-
777
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
778
-
779
- ### Issue 1: Doctor False Positive
780
-
781
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
782
-
783
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
784
-
785
- ### Issue 2: Orphaned Vectors and FTS Entries
786
-
787
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
788
-
789
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
790
-
791
- **Impact:**
792
- - 141,651 orphaned vectors (~875 MB)
793
- - 141,652 orphaned FTS entries
794
- - ~7% of search queries hit phantom results (silently filtered out)
795
- - Database: 1.96 GB (should have been ~1 GB)
796
-
797
- **Fix (three parts):**
798
-
799
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
800
- ```sql
801
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
802
- BEGIN
803
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
804
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
805
- END;
806
- ```
807
-
808
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
809
-
810
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
811
-
812
- **Cleanup results:**
813
- - 141,651 orphaned vectors removed
814
- - FTS rebuilt from 73,813 chunks in 5.7s
815
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
816
- - Verification: chunks = FTS entries = 73,813. Match: YES
817
- - Zero orphans remaining
818
-
819
- ### Side Discovery: Plaintext SA Token
820
-
821
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
822
-
823
- ### Product Rule Established
824
-
825
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
826
-
827
- ## Files Changed
828
-
829
- | File | Change |
830
- |------|--------|
831
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
832
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
833
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
834
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
835
-
836
- ## Related (wip-secrets-ios-private)
837
-
838
- | File | What |
839
- |------|------|
840
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
841
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
842
-
843
- ## Status
844
-
845
- - Code deployed and running (cleanup already executed)
846
- - Not yet committed / PR'd / released
847
- - Needs: branch, commit, PR, merge, `wip-release patch`
848
-
849
- ## 0.7.12 (2026-03-13)
850
-
851
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
852
-
853
- **Date:** 2026-03-13
854
- **Author:** CC-Mini
855
- **Session:** memory-db-fix
856
-
857
- ---
858
-
859
- ## What Happened
860
-
861
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
862
-
863
- ### Issue 1: Doctor False Positive
864
-
865
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
866
-
867
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
868
-
869
- ### Issue 2: Orphaned Vectors and FTS Entries
870
-
871
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
872
-
873
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
874
-
875
- **Impact:**
876
- - 141,651 orphaned vectors (~875 MB)
877
- - 141,652 orphaned FTS entries
878
- - ~7% of search queries hit phantom results (silently filtered out)
879
- - Database: 1.96 GB (should have been ~1 GB)
880
-
881
- **Fix (three parts):**
882
-
883
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
884
- ```sql
885
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
886
- BEGIN
887
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
888
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
889
- END;
890
- ```
891
-
892
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
893
-
894
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
895
-
896
- **Cleanup results:**
897
- - 141,651 orphaned vectors removed
898
- - FTS rebuilt from 73,813 chunks in 5.7s
899
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
900
- - Verification: chunks = FTS entries = 73,813. Match: YES
901
- - Zero orphans remaining
902
-
903
- ### Side Discovery: Plaintext SA Token
904
-
905
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
906
-
907
- ### Product Rule Established
908
-
909
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
910
-
911
- ## Files Changed
912
-
913
- | File | Change |
914
- |------|--------|
915
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
916
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
917
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
918
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
919
-
920
- ## Related (wip-secrets-ios-private)
921
-
922
- | File | What |
923
- |------|------|
924
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
925
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
926
-
927
- ## Status
928
-
929
- - Code deployed and running (cleanup already executed)
930
- - Not yet committed / PR'd / released
931
- - Needs: branch, commit, PR, merge, `wip-release patch`
932
-
933
- ## 0.7.11 (2026-03-13)
934
-
935
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
936
-
937
- **Date:** 2026-03-13
938
- **Author:** CC-Mini
939
- **Session:** memory-db-fix
940
-
941
- ---
942
-
943
- ## What Happened
944
-
945
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
946
-
947
- ### Issue 1: Doctor False Positive
948
-
949
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
950
-
951
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
952
-
953
- ### Issue 2: Orphaned Vectors and FTS Entries
954
-
955
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
956
-
957
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
958
-
959
- **Impact:**
960
- - 141,651 orphaned vectors (~875 MB)
961
- - 141,652 orphaned FTS entries
962
- - ~7% of search queries hit phantom results (silently filtered out)
963
- - Database: 1.96 GB (should have been ~1 GB)
964
-
965
- **Fix (three parts):**
966
-
967
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
968
- ```sql
969
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
970
- BEGIN
971
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
972
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
973
- END;
974
- ```
975
-
976
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
977
-
978
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
979
-
980
- **Cleanup results:**
981
- - 141,651 orphaned vectors removed
982
- - FTS rebuilt from 73,813 chunks in 5.7s
983
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
984
- - Verification: chunks = FTS entries = 73,813. Match: YES
985
- - Zero orphans remaining
986
-
987
- ### Side Discovery: Plaintext SA Token
988
-
989
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
990
-
991
- ### Product Rule Established
992
-
993
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
994
-
995
- ## Files Changed
996
-
997
- | File | Change |
998
- |------|--------|
999
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
1000
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
1001
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
1002
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
1003
-
1004
- ## Related (wip-secrets-ios-private)
1005
-
1006
- | File | What |
1007
- |------|------|
1008
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
1009
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
1010
-
1011
- ## Status
1012
-
1013
- - Code deployed and running (cleanup already executed)
1014
- - Not yet committed / PR'd / released
1015
- - Needs: branch, commit, PR, merge, `wip-release patch`
1016
-
1017
- ## 0.7.10 (2026-03-13)
1018
-
1019
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
1020
-
1021
- **Date:** 2026-03-13
1022
- **Author:** CC-Mini
1023
- **Session:** memory-db-fix
1024
-
1025
- ---
1026
-
1027
- ## What Happened
1028
-
1029
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
1030
-
1031
- ### Issue 1: Doctor False Positive
1032
-
1033
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
1034
-
1035
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
1036
-
1037
- ### Issue 2: Orphaned Vectors and FTS Entries
1038
-
1039
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
1040
-
1041
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
1042
-
1043
- **Impact:**
1044
- - 141,651 orphaned vectors (~875 MB)
1045
- - 141,652 orphaned FTS entries
1046
- - ~7% of search queries hit phantom results (silently filtered out)
1047
- - Database: 1.96 GB (should have been ~1 GB)
1048
-
1049
- **Fix (three parts):**
1050
-
1051
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
1052
- ```sql
1053
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
1054
- BEGIN
1055
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
1056
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
1057
- END;
1058
- ```
1059
-
1060
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
1061
-
1062
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
1063
-
1064
- **Cleanup results:**
1065
- - 141,651 orphaned vectors removed
1066
- - FTS rebuilt from 73,813 chunks in 5.7s
1067
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
1068
- - Verification: chunks = FTS entries = 73,813. Match: YES
1069
- - Zero orphans remaining
1070
-
1071
- ### Side Discovery: Plaintext SA Token
1072
-
1073
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
1074
-
1075
- ### Product Rule Established
1076
-
1077
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
1078
-
1079
- ## Files Changed
1080
-
1081
- | File | Change |
1082
- |------|--------|
1083
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
1084
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
1085
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
1086
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
1087
-
1088
- ## Related (wip-secrets-ios-private)
1089
-
1090
- | File | What |
1091
- |------|------|
1092
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
1093
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
1094
-
1095
- ## Status
1096
-
1097
- - Code deployed and running (cleanup already executed)
1098
- - Not yet committed / PR'd / released
1099
- - Needs: branch, commit, PR, merge, `wip-release patch`
1100
-
1101
- ## 0.7.9 (2026-03-13)
1102
-
1103
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
1104
-
1105
- **Date:** 2026-03-13
1106
- **Author:** CC-Mini
1107
- **Session:** memory-db-fix
1108
-
1109
- ---
1110
-
1111
- ## What Happened
1112
-
1113
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
1114
-
1115
- ### Issue 1: Doctor False Positive
1116
-
1117
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
1118
-
1119
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
1120
-
1121
- ### Issue 2: Orphaned Vectors and FTS Entries
1122
-
1123
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
1124
-
1125
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
1126
-
1127
- **Impact:**
1128
- - 141,651 orphaned vectors (~875 MB)
1129
- - 141,652 orphaned FTS entries
1130
- - ~7% of search queries hit phantom results (silently filtered out)
1131
- - Database: 1.96 GB (should have been ~1 GB)
1132
-
1133
- **Fix (three parts):**
1134
-
1135
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
1136
- ```sql
1137
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
1138
- BEGIN
1139
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
1140
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
1141
- END;
1142
- ```
1143
-
1144
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
1145
-
1146
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
1147
-
1148
- **Cleanup results:**
1149
- - 141,651 orphaned vectors removed
1150
- - FTS rebuilt from 73,813 chunks in 5.7s
1151
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
1152
- - Verification: chunks = FTS entries = 73,813. Match: YES
1153
- - Zero orphans remaining
1154
-
1155
- ### Side Discovery: Plaintext SA Token
1156
-
1157
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
1158
-
1159
- ### Product Rule Established
1160
-
1161
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
1162
-
1163
- ## Files Changed
1164
-
1165
- | File | Change |
1166
- |------|--------|
1167
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
1168
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
1169
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
1170
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
1171
-
1172
- ## Related (wip-secrets-ios-private)
1173
-
1174
- | File | What |
1175
- |------|------|
1176
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
1177
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
1178
-
1179
- ## Status
1180
-
1181
- - Code deployed and running (cleanup already executed)
1182
- - Not yet committed / PR'd / released
1183
- - Needs: branch, commit, PR, merge, `wip-release patch`
1184
-
1185
- ## 0.7.8 (2026-03-13)
1186
-
1187
- # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
1188
-
1189
- **Date:** 2026-03-13
1190
- **Author:** CC-Mini
1191
- **Session:** memory-db-fix
1192
-
1193
- ---
1194
-
1195
- ## What Happened
1196
-
1197
- Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
1198
-
1199
- ### Issue 1: Doctor False Positive
1200
-
1201
- `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
1202
-
1203
- **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
1204
-
1205
- ### Issue 2: Orphaned Vectors and FTS Entries
1206
-
1207
- On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
1208
-
1209
- The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
1210
-
1211
- **Impact:**
1212
- - 141,651 orphaned vectors (~875 MB)
1213
- - 141,652 orphaned FTS entries
1214
- - ~7% of search queries hit phantom results (silently filtered out)
1215
- - Database: 1.96 GB (should have been ~1 GB)
1216
-
1217
- **Fix (three parts):**
1218
-
1219
- 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
1220
- ```sql
1221
- CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
1222
- BEGIN
1223
- DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
1224
- INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
1225
- END;
1226
- ```
1227
-
1228
- 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
1229
-
1230
- 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
1231
-
1232
- **Cleanup results:**
1233
- - 141,651 orphaned vectors removed
1234
- - FTS rebuilt from 73,813 chunks in 5.7s
1235
- - Database: 1.96 GB -> 1.45 GB (525 MB saved)
1236
- - Verification: chunks = FTS entries = 73,813. Match: YES
1237
- - Zero orphans remaining
1238
-
1239
- ### Side Discovery: Plaintext SA Token
1240
-
1241
- During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
1242
-
1243
- ### Product Rule Established
1244
-
1245
- Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
1246
-
1247
- ## Files Changed
1248
-
1249
- | File | Change |
1250
- |------|--------|
1251
- | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
1252
- | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
1253
- | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
1254
- | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
1255
-
1256
- ## Related (wip-secrets-ios-private)
1257
-
1258
- | File | What |
1259
- |------|------|
1260
- | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
1261
- | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
1262
-
1263
- ## Status
1264
-
1265
- - Code deployed and running (cleanup already executed)
1266
- - Not yet committed / PR'd / released
1267
- - Needs: branch, commit, PR, merge, `wip-release patch`
1268
-
1269
- ## 0.7.7 (2026-03-13)
1270
-
1271
- Update install prompt to new standard format. Replaces old 3-question prompt with 4 explain questions, installed check, and dry-run before install.
1272
-
1273
- ## 0.7.6 (2026-03-13)
1274
-
1275
- Update LDM delegation tips
1276
-
1277
- ## 0.7.5 (2026-03-13)
1278
-
1279
- # Release Notes: Memory Crystal v0.7.5
1280
-
1281
- ## LDM OS Integration
1282
-
1283
- Memory Crystal now works with LDM OS when it's available.
1284
-
1285
- ### crystal init delegates to ldm install
1286
-
1287
- When the `ldm` CLI exists on PATH, `crystal init` delegates generic deployment to it. LDM OS handles the scaffold, interface detection, and extension deployment. Memory Crystal keeps its own setup: database backup, role configuration, pairing, cron jobs.
1288
-
1289
- When `ldm` isn't available, `crystal init` works standalone like it always has. No new dependencies. No breaking changes.
1290
-
1291
- ### LDM OS tip
1292
-
1293
- After install completes, Memory Crystal prints a tip: "Run `ldm install` to see more skills you can add." Helps users discover the rest of the ecosystem.
1294
-
1295
- ### Part of LDM OS
1296
-
1297
- README now includes a "Part of LDM OS" section linking back to the LDM OS repo. Memory Crystal installs into LDM OS, the local runtime for AI agents.
1298
-
1299
- ## 0.7.4 (2026-03-11)
1300
-
1301
- MCP fix (OPENCLAW_HOME env var), AgentId reads from LDM config instead of hardcoding, MCP registrations moved to user-level, 33 stale branches renamed, QMD v1.1.6 analysis documented
1302
-
1303
- ## 0.7.3 (2026-03-10)
1304
-
1305
- Fix MCP registration to include OPENCLAW_HOME env var for memory-crystal MCP server
1306
-
1307
- ## 0.7.2 (2026-03-05)
1308
-
1309
- Fix MCP detection in doctor and installer to check project-level and user-scope registrations
1310
-
1311
- ## 0.7.1 (2026-03-05)
1312
-
1313
- Database backup, verification, and import in installer
1314
-
1315
- ## 0.7.0 (2026-03-05)
1316
-
1317
- Delta sync, file sync, intelligent install & update
1318
-
1319
- ## 0.6.1 (2026-03-05)
1320
-
1321
- Search quality: deep search with LLM query expansion + re-ranking, MCP sampling design, updated docs
1322
-
1323
- ## 0.6.0 (2026-03-04)
1324
-
1325
- Dream Weaver integration, Crystal Core gateway, staging pipeline, commands channel.
1326
-
1327
- - Dream Weaver narrative consolidation via `crystal dream-weave` (imports engine from dream-weaver-protocol)
1328
- - Crystal Core gateway (`crystal serve`) on localhost:18790, OpenAI-compatible endpoint
1329
- - Staging pipeline for new agents from relay (auto-detect, stage, backfill, dream-weave)
1330
- - Commands channel on relay Worker (nodes send commands to Core, Core sends results back)
1331
- - OpenClaw raw data sync to LDM after every agent_end turn (sessions, workspace, daily logs)
1332
- - Relay command support in cc-hook.ts (`sendCommand()` export)
1333
- - Harness-aware init flow (OpenClaw vs Claude Code, Core vs Node)
1334
- - Poller now detects new agents and routes to staging before live ingest
1335
-
1336
- ## 0.5.0 (2026-03-04)
1337
-
1338
- Init discovery, bulk copy, OpenClaw parser, backfill, CE migration. Reorganize ai/ to ai/product/.
1339
-
1340
- - `crystal init` discovers session files on the current machine (Claude Code + OpenClaw)
1341
- - `crystal backfill` embeds raw transcript files from LDM (Core: local embed, Node: relay to Core)
1342
- - `crystal migrate-embeddings` migrates context-embeddings.sqlite chunks into crystal.db ($0, copies embeddings directly)
1343
- - `src/discover.ts` auto-detects installed harnesses and session file locations
1344
- - `src/bulk-copy.ts` copies raw files to LDM transcripts (idempotent, skip if same size)
1345
- - `src/oc-backfill.ts` parses OpenClaw JSONL format into standard message format
1346
- - Workspace path added to LDM (`~/.ldm/agents/{id}/memory/workspace/`)
1347
-
1348
-
1349
-
1350
- ## 0.4.1 (2026-03-03)
1351
-
1352
- Crystal Core/Node architecture, crystal doctor, crystal backup, crystal bridge, SKILL.md onboarding rewrite
1353
-
1354
- ## 0.3.3 (2026-03-02)
1355
-
1356
- Fix bin entries: crystal and crystal-mcp commands were missing from v0.3.2 due to npm stripping ./ prefix paths
1357
-
1358
- ## 0.3.2 (2026-03-02)
1359
-
1360
- Rewrite SKILL.md as complete agent install guide. Add crystal-mcp binary for clean MCP config. CLI search output matches MCP server (freshness icons, numbered results). Agents can now auto-detect and install for Claude Code CLI, Claude Desktop, and OpenClaw.
1361
-
1362
- ## 0.3.1 (2026-03-02)
1363
-
1364
- Fix npm package: exclude ai/ folder from published tarball
1365
-
1366
- ## 0.3.0 (2026-03-02)
1367
-
1368
- Phase 1 continuous capture, Cloud MCP server, QR pairing, crystal init, docs overhaul
1369
-
1370
- ## 0.2.0 (2026-02-28)
1371
-
1372
- README overhaul, relay encryption, QR pairing spec, Grok/Lesa feedback, disable auto dev-updates