@remnic/core 9.3.637 → 9.3.639

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 (279) hide show
  1. package/dist/access-cli.js +29 -29
  2. package/dist/access-http.d.ts +56 -5
  3. package/dist/access-http.js +15 -13
  4. package/dist/access-mcp.d.ts +4 -4
  5. package/dist/access-mcp.js +14 -12
  6. package/dist/access-schema.d.ts +3 -0
  7. package/dist/access-schema.js +1 -1
  8. package/dist/{access-service-GVOE5U3C.d.ts → access-service-jyYute38.d.ts} +4 -2
  9. package/dist/access-service.d.ts +4 -4
  10. package/dist/access-service.js +12 -10
  11. package/dist/action-confidence.d.ts +1 -1
  12. package/dist/active-memory-bridge.d.ts +1 -1
  13. package/dist/active-recall.d.ts +1 -1
  14. package/dist/active-recall.js +1 -1
  15. package/dist/{auto-sync-RFADEHIQ.js → auto-sync-54QQHOG5.js} +4 -4
  16. package/dist/behavior-learner.d.ts +1 -1
  17. package/dist/behavior-signals.d.ts +1 -1
  18. package/dist/bootstrap.d.ts +3 -3
  19. package/dist/briefing.d.ts +1 -1
  20. package/dist/briefing.js +3 -3
  21. package/dist/buffer-surprise-report.d.ts +1 -1
  22. package/dist/buffer.d.ts +1 -1
  23. package/dist/calibration.d.ts +1 -1
  24. package/dist/calibration.js +1 -1
  25. package/dist/causal-behavior.d.ts +1 -1
  26. package/dist/causal-behavior.js +2 -2
  27. package/dist/causal-chain.js +2 -2
  28. package/dist/causal-consolidation.d.ts +1 -1
  29. package/dist/causal-consolidation.js +7 -7
  30. package/dist/causal-retrieval.js +2 -2
  31. package/dist/causal-trajectory-graph.js +1 -1
  32. package/dist/causal-trajectory.js +1 -1
  33. package/dist/{chunk-TFICNXXU.js → chunk-2BHNQRE5.js} +1153 -294
  34. package/dist/chunk-2BHNQRE5.js.map +1 -0
  35. package/dist/{chunk-3RDYU3JS.js → chunk-3AZDLWDW.js} +3 -3
  36. package/dist/{chunk-FPNQF475.js → chunk-3F7RMHC4.js} +1 -1
  37. package/dist/chunk-3F7RMHC4.js.map +1 -0
  38. package/dist/{chunk-3EJ5OOZ3.js → chunk-3SF7QNKF.js} +3 -3
  39. package/dist/{chunk-NFNQ7TWF.js → chunk-4VTVCWVB.js} +20 -12
  40. package/dist/chunk-4VTVCWVB.js.map +1 -0
  41. package/dist/{chunk-XM6M6DHG.js → chunk-52XI77OQ.js} +204 -13
  42. package/dist/chunk-52XI77OQ.js.map +1 -0
  43. package/dist/{chunk-6BDVBBBY.js → chunk-666A3MOW.js} +88 -30
  44. package/dist/chunk-666A3MOW.js.map +1 -0
  45. package/dist/{chunk-242XFZ36.js → chunk-7OH7KPF5.js} +2 -2
  46. package/dist/{chunk-HZVIYZYN.js → chunk-7R37SOT4.js} +6 -6
  47. package/dist/{chunk-7A2QKUUA.js → chunk-7XRSLMUD.js} +2 -2
  48. package/dist/{chunk-723OMPUI.js → chunk-A3BS64GV.js} +7 -1
  49. package/dist/chunk-A3BS64GV.js.map +1 -0
  50. package/dist/{chunk-JCLECECB.js → chunk-A3UPMOJZ.js} +2 -2
  51. package/dist/{chunk-YCX45GOQ.js → chunk-AFH2JXSF.js} +2 -2
  52. package/dist/{chunk-BK35NOJL.js → chunk-BB6FNMMB.js} +52 -6
  53. package/dist/chunk-BB6FNMMB.js.map +1 -0
  54. package/dist/{chunk-3XNMN242.js → chunk-BTY5XQG3.js} +7 -7
  55. package/dist/{chunk-QHXW3LZV.js → chunk-C3EJ3UIS.js} +3 -3
  56. package/dist/{chunk-A3HKTPPV.js → chunk-C63WC454.js} +12 -1
  57. package/dist/chunk-C63WC454.js.map +1 -0
  58. package/dist/{chunk-4S3N6HFG.js → chunk-C6XO6ONP.js} +2 -2
  59. package/dist/{chunk-WD2W4234.js → chunk-CDHRUNBX.js} +11 -2
  60. package/dist/chunk-CDHRUNBX.js.map +1 -0
  61. package/dist/{chunk-YQNADJCT.js → chunk-CMZLMIZI.js} +2 -2
  62. package/dist/{chunk-KVDUDYEN.js → chunk-DDRNDPX4.js} +2 -2
  63. package/dist/{chunk-PW6GURU3.js → chunk-EKIQBGAY.js} +2 -2
  64. package/dist/{chunk-QJGTSCJN.js → chunk-FGRV3X3Y.js} +19 -19
  65. package/dist/{chunk-2IT7WFYE.js → chunk-FWIROLS6.js} +2 -1
  66. package/dist/chunk-FWIROLS6.js.map +1 -0
  67. package/dist/{chunk-X7EJF46S.js → chunk-H4RWKZE2.js} +2 -2
  68. package/dist/{chunk-A6D7A2FW.js → chunk-IHG27THY.js} +4 -4
  69. package/dist/{chunk-PUEAEQSN.js → chunk-ISMZIMD3.js} +2 -2
  70. package/dist/{chunk-LEG7XWS2.js → chunk-IXSTQGYV.js} +2 -2
  71. package/dist/{chunk-CMN5AWAZ.js → chunk-J2KFC47S.js} +2 -2
  72. package/dist/{chunk-K47C6M2C.js → chunk-M75TBFKQ.js} +2 -2
  73. package/dist/{chunk-7V2SGZ3H.js → chunk-NE566K4E.js} +2 -2
  74. package/dist/{chunk-YROCXMCK.js → chunk-RJGPH2Q3.js} +2 -2
  75. package/dist/{chunk-UXFOGILU.js → chunk-SBHQBC37.js} +2 -2
  76. package/dist/{chunk-QYGIQ5NM.js → chunk-SHHT4JTC.js} +2 -2
  77. package/dist/{chunk-TQOU3VAT.js → chunk-SSOMTUCA.js} +1 -1
  78. package/dist/{chunk-NRST7W5Q.js → chunk-UI2UP7XX.js} +2 -2
  79. package/dist/{chunk-C4KKM62E.js → chunk-UU5LHD6J.js} +2 -2
  80. package/dist/{chunk-EWC6W6AB.js → chunk-UXA5L2DZ.js} +2 -2
  81. package/dist/{chunk-XL7FK7PJ.js → chunk-Y56J7CXW.js} +33 -16
  82. package/dist/{chunk-XL7FK7PJ.js.map → chunk-Y56J7CXW.js.map} +1 -1
  83. package/dist/{cli-B-fHk59D.d.ts → cli-A4AIhv9e.d.ts} +3 -3
  84. package/dist/cli.d.ts +5 -5
  85. package/dist/cli.js +28 -27
  86. package/dist/compounding/engine.d.ts +1 -1
  87. package/dist/compounding/engine.js +3 -3
  88. package/dist/compounding/preference-consolidator.d.ts +1 -1
  89. package/dist/compression-optimizer.d.ts +1 -1
  90. package/dist/config.d.ts +1 -1
  91. package/dist/config.js +1 -1
  92. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  93. package/dist/connectors/codex-materialize-runner.js +3 -3
  94. package/dist/connectors/codex-materialize.d.ts +1 -1
  95. package/dist/connectors/index.d.ts +1 -1
  96. package/dist/connectors/index.js +3 -3
  97. package/dist/consolidation-provenance-check.d.ts +1 -1
  98. package/dist/consolidation-undo.d.ts +1 -1
  99. package/dist/contradiction/index.d.ts +1 -1
  100. package/dist/conversation-index/backend.d.ts +1 -1
  101. package/dist/conversation-index/chunker.d.ts +1 -1
  102. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  103. package/dist/conversation-index/indexer.d.ts +1 -1
  104. package/dist/conversation-index/search.d.ts +1 -1
  105. package/dist/day-summary.d.ts +1 -1
  106. package/dist/delinearize.d.ts +1 -1
  107. package/dist/direct-answer-wiring.d.ts +1 -1
  108. package/dist/direct-answer.d.ts +1 -1
  109. package/dist/embedding-fallback.d.ts +1 -1
  110. package/dist/enrichment/index.d.ts +1 -1
  111. package/dist/entity-retrieval.d.ts +1 -1
  112. package/dist/entity-retrieval.js +3 -3
  113. package/dist/entity-schema.d.ts +1 -1
  114. package/dist/explicit-capture.d.ts +3 -3
  115. package/dist/extraction-judge-telemetry.d.ts +1 -1
  116. package/dist/extraction-judge-training.d.ts +1 -1
  117. package/dist/extraction-judge.d.ts +1 -1
  118. package/dist/extraction-judge.js +2 -2
  119. package/dist/extraction.d.ts +1 -1
  120. package/dist/extraction.js +2 -2
  121. package/dist/fallback-llm.d.ts +1 -1
  122. package/dist/fallback-llm.js +1 -1
  123. package/dist/{graph-edge-decay-5ZOK7ZNO.js → graph-edge-decay-PUFNHOBS.js} +2 -2
  124. package/dist/graph-snapshot.js +2 -2
  125. package/dist/graph.d.ts +3 -0
  126. package/dist/graph.js +1 -1
  127. package/dist/identity-continuity.d.ts +1 -1
  128. package/dist/importance.d.ts +1 -1
  129. package/dist/index.d.ts +9 -9
  130. package/dist/index.js +40 -40
  131. package/dist/intent.d.ts +1 -1
  132. package/dist/lcm/engine.d.ts +1 -1
  133. package/dist/lcm/index.d.ts +1 -1
  134. package/dist/lcm/tools.d.ts +1 -1
  135. package/dist/lifecycle.d.ts +1 -1
  136. package/dist/live-connectors-runner.d.ts +1 -1
  137. package/dist/local-llm.d.ts +1 -1
  138. package/dist/maintenance/memory-governance-cron.d.ts +8 -0
  139. package/dist/maintenance/memory-governance-cron.js +1 -1
  140. package/dist/maintenance/memory-governance.d.ts +1 -1
  141. package/dist/maintenance/memory-governance.js +3 -3
  142. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  143. package/dist/maintenance/rebuild-memory-projection.js +4 -4
  144. package/dist/mcp-memory-inspector-app.d.ts +4 -4
  145. package/dist/memory-action-policy.d.ts +1 -1
  146. package/dist/memory-cache.d.ts +1 -1
  147. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  148. package/dist/memory-projection-store.d.ts +1 -1
  149. package/dist/memory-provenance.d.ts +1 -1
  150. package/dist/memory-worth-outcomes.d.ts +1 -1
  151. package/dist/models-json.d.ts +1 -1
  152. package/dist/namespaces/migrate.d.ts +1 -1
  153. package/dist/namespaces/migrate.js +4 -4
  154. package/dist/namespaces/principal.d.ts +1 -1
  155. package/dist/namespaces/search.d.ts +1 -1
  156. package/dist/namespaces/storage.d.ts +1 -1
  157. package/dist/namespaces/storage.js +3 -3
  158. package/dist/native-knowledge.d.ts +1 -1
  159. package/dist/operator-toolkit.d.ts +1 -1
  160. package/dist/operator-toolkit.js +8 -8
  161. package/dist/{orchestrator-CoqytbK_.d.ts → orchestrator-BEDTiuEO.d.ts} +20 -5
  162. package/dist/orchestrator.d.ts +3 -3
  163. package/dist/orchestrator.js +24 -24
  164. package/dist/patterns-cli.d.ts +1 -1
  165. package/dist/policy-runtime.d.ts +1 -1
  166. package/dist/qmd-recall-cache.d.ts +1 -1
  167. package/dist/qmd.d.ts +1 -1
  168. package/dist/recall-disclosure-escalation.d.ts +1 -1
  169. package/dist/recall-explain-renderer.d.ts +1 -1
  170. package/dist/recall-explain-renderer.js +3 -3
  171. package/dist/recall-planner-llm.d.ts +1 -1
  172. package/dist/recall-planner-llm.js +1 -1
  173. package/dist/recall-state.d.ts +3 -1
  174. package/dist/recall-state.js +1 -1
  175. package/dist/recall-tag-filter.d.ts +1 -1
  176. package/dist/recall-xray-cli.d.ts +1 -1
  177. package/dist/recall-xray-cli.js +4 -4
  178. package/dist/recall-xray-renderer.d.ts +1 -1
  179. package/dist/recall-xray-renderer.js +3 -3
  180. package/dist/recall-xray.d.ts +1 -1
  181. package/dist/recall-xray.js +2 -2
  182. package/dist/resolve-auth-token.d.ts +1 -1
  183. package/dist/resume-bundles.js +4 -4
  184. package/dist/retrieval-agents.d.ts +1 -1
  185. package/dist/retrieval-tiers.d.ts +1 -1
  186. package/dist/routing/engine.d.ts +1 -1
  187. package/dist/routing/store.d.ts +1 -1
  188. package/dist/search/embed-helper.d.ts +1 -1
  189. package/dist/search/factory.d.ts +1 -1
  190. package/dist/search/index.d.ts +1 -1
  191. package/dist/search/lancedb-backend.d.ts +1 -1
  192. package/dist/search/meilisearch-backend.d.ts +1 -1
  193. package/dist/search/noop-backend.d.ts +1 -1
  194. package/dist/search/orama-backend.d.ts +1 -1
  195. package/dist/search/port.d.ts +1 -1
  196. package/dist/search/remote-backend.d.ts +1 -1
  197. package/dist/{semantic-consolidation-BPs6BURk.d.ts → semantic-consolidation-Byut1ufK.d.ts} +1 -1
  198. package/dist/semantic-consolidation.d.ts +2 -2
  199. package/dist/semantic-consolidation.js +4 -4
  200. package/dist/semantic-rule-promotion.js +3 -3
  201. package/dist/semantic-rule-verifier.d.ts +1 -1
  202. package/dist/semantic-rule-verifier.js +3 -3
  203. package/dist/session-observer-bands.d.ts +1 -1
  204. package/dist/session-observer-state.d.ts +1 -1
  205. package/dist/shared-context/manager.d.ts +1 -1
  206. package/dist/signal.d.ts +1 -1
  207. package/dist/storage.d.ts +1 -1
  208. package/dist/storage.js +2 -2
  209. package/dist/summarizer.d.ts +1 -1
  210. package/dist/summarizer.js +3 -3
  211. package/dist/summary-snapshot.d.ts +1 -1
  212. package/dist/temporal-supersession.d.ts +1 -1
  213. package/dist/temporal-validity.d.ts +1 -1
  214. package/dist/threading.d.ts +1 -1
  215. package/dist/tier-migration.d.ts +1 -1
  216. package/dist/tier-routing.d.ts +1 -1
  217. package/dist/topics.d.ts +1 -1
  218. package/dist/transcript.d.ts +1 -1
  219. package/dist/transcript.js +2 -2
  220. package/dist/{types-CpMPD8xl.d.ts → types-BzA1FKbg.d.ts} +4 -0
  221. package/dist/types.d.ts +1 -1
  222. package/dist/types.js +1 -1
  223. package/dist/utility-runtime.d.ts +1 -1
  224. package/dist/verified-recall.js +3 -3
  225. package/package.json +1 -1
  226. package/src/access-http.test.ts +110 -2
  227. package/src/access-http.ts +117 -1
  228. package/src/access-mcp.ts +15 -6
  229. package/src/access-schema.ts +14 -0
  230. package/src/access-service-namespace.test.ts +740 -0
  231. package/src/access-service.ts +226 -4
  232. package/src/config.ts +14 -0
  233. package/src/fallback-llm.ts +16 -0
  234. package/src/graph.ts +39 -17
  235. package/src/index.ts +9 -1
  236. package/src/maintenance/memory-governance-cron.ts +113 -30
  237. package/src/orchestrator.ts +1456 -336
  238. package/src/recall-state.ts +3 -0
  239. package/src/types.ts +4 -0
  240. package/dist/chunk-2IT7WFYE.js.map +0 -1
  241. package/dist/chunk-6BDVBBBY.js.map +0 -1
  242. package/dist/chunk-723OMPUI.js.map +0 -1
  243. package/dist/chunk-A3HKTPPV.js.map +0 -1
  244. package/dist/chunk-BK35NOJL.js.map +0 -1
  245. package/dist/chunk-FPNQF475.js.map +0 -1
  246. package/dist/chunk-NFNQ7TWF.js.map +0 -1
  247. package/dist/chunk-TFICNXXU.js.map +0 -1
  248. package/dist/chunk-WD2W4234.js.map +0 -1
  249. package/dist/chunk-XM6M6DHG.js.map +0 -1
  250. /package/dist/{auto-sync-RFADEHIQ.js.map → auto-sync-54QQHOG5.js.map} +0 -0
  251. /package/dist/{chunk-3RDYU3JS.js.map → chunk-3AZDLWDW.js.map} +0 -0
  252. /package/dist/{chunk-3EJ5OOZ3.js.map → chunk-3SF7QNKF.js.map} +0 -0
  253. /package/dist/{chunk-242XFZ36.js.map → chunk-7OH7KPF5.js.map} +0 -0
  254. /package/dist/{chunk-HZVIYZYN.js.map → chunk-7R37SOT4.js.map} +0 -0
  255. /package/dist/{chunk-7A2QKUUA.js.map → chunk-7XRSLMUD.js.map} +0 -0
  256. /package/dist/{chunk-JCLECECB.js.map → chunk-A3UPMOJZ.js.map} +0 -0
  257. /package/dist/{chunk-YCX45GOQ.js.map → chunk-AFH2JXSF.js.map} +0 -0
  258. /package/dist/{chunk-3XNMN242.js.map → chunk-BTY5XQG3.js.map} +0 -0
  259. /package/dist/{chunk-QHXW3LZV.js.map → chunk-C3EJ3UIS.js.map} +0 -0
  260. /package/dist/{chunk-4S3N6HFG.js.map → chunk-C6XO6ONP.js.map} +0 -0
  261. /package/dist/{chunk-YQNADJCT.js.map → chunk-CMZLMIZI.js.map} +0 -0
  262. /package/dist/{chunk-KVDUDYEN.js.map → chunk-DDRNDPX4.js.map} +0 -0
  263. /package/dist/{chunk-PW6GURU3.js.map → chunk-EKIQBGAY.js.map} +0 -0
  264. /package/dist/{chunk-QJGTSCJN.js.map → chunk-FGRV3X3Y.js.map} +0 -0
  265. /package/dist/{chunk-X7EJF46S.js.map → chunk-H4RWKZE2.js.map} +0 -0
  266. /package/dist/{chunk-A6D7A2FW.js.map → chunk-IHG27THY.js.map} +0 -0
  267. /package/dist/{chunk-PUEAEQSN.js.map → chunk-ISMZIMD3.js.map} +0 -0
  268. /package/dist/{chunk-LEG7XWS2.js.map → chunk-IXSTQGYV.js.map} +0 -0
  269. /package/dist/{chunk-CMN5AWAZ.js.map → chunk-J2KFC47S.js.map} +0 -0
  270. /package/dist/{chunk-K47C6M2C.js.map → chunk-M75TBFKQ.js.map} +0 -0
  271. /package/dist/{chunk-7V2SGZ3H.js.map → chunk-NE566K4E.js.map} +0 -0
  272. /package/dist/{chunk-YROCXMCK.js.map → chunk-RJGPH2Q3.js.map} +0 -0
  273. /package/dist/{chunk-UXFOGILU.js.map → chunk-SBHQBC37.js.map} +0 -0
  274. /package/dist/{chunk-QYGIQ5NM.js.map → chunk-SHHT4JTC.js.map} +0 -0
  275. /package/dist/{chunk-TQOU3VAT.js.map → chunk-SSOMTUCA.js.map} +0 -0
  276. /package/dist/{chunk-NRST7W5Q.js.map → chunk-UI2UP7XX.js.map} +0 -0
  277. /package/dist/{chunk-C4KKM62E.js.map → chunk-UU5LHD6J.js.map} +0 -0
  278. /package/dist/{chunk-EWC6W6AB.js.map → chunk-UXA5L2DZ.js.map} +0 -0
  279. /package/dist/{graph-edge-decay-5ZOK7ZNO.js.map → graph-edge-decay-PUFNHOBS.js.map} +0 -0
@@ -6,7 +6,9 @@ import path from "node:path";
6
6
  import test from "node:test";
7
7
 
8
8
  import { EngramAccessInputError, EngramAccessService } from "./access-service.js";
9
+ import { namespaceIdentityToken } from "./namespaces/identity.js";
9
10
  import { namespaceCollectionName } from "./namespaces/search.js";
11
+ import { SecureStoreLockedError } from "./secure-store/index.js";
10
12
  import type { StorageManager } from "./storage.js";
11
13
  import type { PluginConfig } from "./types.js";
12
14
 
@@ -150,6 +152,744 @@ test("memoryBrowse resolves namespace storage for read principals", async () =>
150
152
  assert.deepEqual(getStorageCalls, ["team"]);
151
153
  });
152
154
 
155
+ test("last recall serialization resolves namespace collection-prefixed result paths", async () => {
156
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
157
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-ns-"));
158
+ const teamDir = path.join(
159
+ memoryRoot,
160
+ "namespaces",
161
+ namespaceIdentityToken("team"),
162
+ );
163
+ const memoryPath = path.join(
164
+ teamDir,
165
+ "archive",
166
+ "facts",
167
+ "2026-06-16",
168
+ "fact-001.md",
169
+ );
170
+ const teamMemory = {
171
+ path: memoryPath,
172
+ frontmatter: {
173
+ id: "fact-001",
174
+ created: "2026-06-16T12:00:00.000Z",
175
+ updated: "2026-06-16T12:00:00.000Z",
176
+ category: "fact",
177
+ status: "active",
178
+ tags: ["discord"],
179
+ },
180
+ content: "Agent-authored status update from the channel.",
181
+ };
182
+ const readCalls: Array<{ namespace: string; path: string }> = [];
183
+ const storages: Record<string, StorageManager> = {
184
+ default: {
185
+ dir: memoryRoot,
186
+ async readMemoryByPath(filePath: string) {
187
+ readCalls.push({ namespace: "default", path: filePath });
188
+ return null;
189
+ },
190
+ async getMemoryById() {
191
+ return null;
192
+ },
193
+ } as unknown as StorageManager,
194
+ team: {
195
+ dir: teamDir,
196
+ async readMemoryByPath(filePath: string) {
197
+ readCalls.push({ namespace: "team", path: filePath });
198
+ return filePath === memoryPath ? teamMemory : null;
199
+ },
200
+ async getMemoryById() {
201
+ return null;
202
+ },
203
+ } as unknown as StorageManager,
204
+ };
205
+
206
+ (service as unknown as {
207
+ orchestrator: {
208
+ config: PluginConfig;
209
+ getStorage(namespace: string): Promise<StorageManager>;
210
+ };
211
+ }).orchestrator = {
212
+ config: makeConfig(),
213
+ async getStorage(namespace: string) {
214
+ return storages[namespace] ?? storages.default;
215
+ },
216
+ };
217
+
218
+ const collection = namespaceCollectionName("test-memory", "team", {
219
+ defaultNamespace: "default",
220
+ useLegacyDefaultCollection: false,
221
+ });
222
+ const result = await (service as unknown as {
223
+ serializeRecallResults(
224
+ snapshot: unknown,
225
+ disclosure: "summary",
226
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
227
+ }).serializeRecallResults(
228
+ {
229
+ sessionKey: "session-1",
230
+ recordedAt: "2026-06-16T12:00:00.000Z",
231
+ queryHash: "hash",
232
+ queryLen: 4,
233
+ memoryIds: [],
234
+ namespace: "default",
235
+ resultPaths: [`${collection}/archive/facts/2026-06-16/fact-001.md`],
236
+ },
237
+ "summary",
238
+ );
239
+
240
+ assert.equal(result.length, 1);
241
+ assert.equal(result[0].id, "fact-001");
242
+ assert.equal(result[0].path, memoryPath);
243
+ assert.equal(result[0].status, "archived");
244
+ assert.ok(result[0].preview.includes("Agent-authored status update"));
245
+ assert.ok(
246
+ readCalls.some(
247
+ (call) => call.namespace === "team" && call.path === memoryPath,
248
+ ),
249
+ "expected collection-prefixed result path to resolve through team storage",
250
+ );
251
+ });
252
+
253
+ test("last recall serialization does not fall back after namespace collection misses", async () => {
254
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
255
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-ns-miss-"));
256
+ const defaultMemoryPath = path.join(
257
+ memoryRoot,
258
+ "facts",
259
+ "2026-06-16",
260
+ "fact-001.md",
261
+ );
262
+ const defaultMemory = {
263
+ path: defaultMemoryPath,
264
+ frontmatter: {
265
+ id: "fact-001",
266
+ created: "2026-06-16T12:00:00.000Z",
267
+ updated: "2026-06-16T12:00:00.000Z",
268
+ category: "fact",
269
+ status: "active",
270
+ },
271
+ content: "Default namespace content should not be reused.",
272
+ };
273
+ const teamDir = path.join(
274
+ memoryRoot,
275
+ "namespaces",
276
+ namespaceIdentityToken("team"),
277
+ );
278
+ const readCalls: Array<{ namespace: string; path: string }> = [];
279
+ const storages: Record<string, StorageManager> = {
280
+ default: {
281
+ dir: memoryRoot,
282
+ async readMemoryByPath(filePath: string) {
283
+ readCalls.push({ namespace: "default", path: filePath });
284
+ return filePath === defaultMemoryPath ? defaultMemory : null;
285
+ },
286
+ async getMemoryById() {
287
+ return null;
288
+ },
289
+ } as unknown as StorageManager,
290
+ team: {
291
+ dir: teamDir,
292
+ async readMemoryByPath(filePath: string) {
293
+ readCalls.push({ namespace: "team", path: filePath });
294
+ return null;
295
+ },
296
+ async getMemoryById() {
297
+ return null;
298
+ },
299
+ } as unknown as StorageManager,
300
+ };
301
+
302
+ (service as unknown as {
303
+ orchestrator: {
304
+ config: PluginConfig;
305
+ getStorage(namespace: string): Promise<StorageManager>;
306
+ };
307
+ }).orchestrator = {
308
+ config: makeConfig(),
309
+ async getStorage(namespace: string) {
310
+ return storages[namespace] ?? storages.default;
311
+ },
312
+ };
313
+
314
+ const collection = namespaceCollectionName("test-memory", "team", {
315
+ defaultNamespace: "default",
316
+ useLegacyDefaultCollection: false,
317
+ });
318
+ const result = await (service as unknown as {
319
+ serializeRecallResults(
320
+ snapshot: unknown,
321
+ disclosure: "summary",
322
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
323
+ }).serializeRecallResults(
324
+ {
325
+ sessionKey: "session-1",
326
+ recordedAt: "2026-06-16T12:00:00.000Z",
327
+ queryHash: "hash",
328
+ queryLen: 4,
329
+ memoryIds: [],
330
+ namespace: "default",
331
+ resultPaths: [`${collection}/2026-06-16/fact-001.md`],
332
+ },
333
+ "summary",
334
+ );
335
+
336
+ assert.deepEqual(result, []);
337
+ assert.ok(
338
+ readCalls.every((call) => call.namespace === "team"),
339
+ "expected recognized collection-prefixed miss not to probe default storage",
340
+ );
341
+ });
342
+
343
+ test("last recall serialization resolves cold collection paths through snapshot storage", async () => {
344
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
345
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-cold-"));
346
+ const coldMemoryPath = path.join(
347
+ memoryRoot,
348
+ "cold",
349
+ "facts",
350
+ "2026-06-16",
351
+ "fact-001.md",
352
+ );
353
+ const coldMemory = {
354
+ path: coldMemoryPath,
355
+ frontmatter: {
356
+ id: "fact-001",
357
+ created: "2026-06-16T12:00:00.000Z",
358
+ updated: "2026-06-16T12:00:00.000Z",
359
+ category: "fact",
360
+ status: "active",
361
+ },
362
+ content: "Cold namespace recall content.",
363
+ };
364
+ const readCalls: string[] = [];
365
+ const storage = {
366
+ dir: memoryRoot,
367
+ async readMemoryByPath(filePath: string) {
368
+ readCalls.push(filePath);
369
+ return filePath === coldMemoryPath ? coldMemory : null;
370
+ },
371
+ async getMemoryById() {
372
+ return null;
373
+ },
374
+ } as unknown as StorageManager;
375
+
376
+ (service as unknown as {
377
+ orchestrator: {
378
+ config: PluginConfig;
379
+ getStorage(namespace: string): Promise<StorageManager>;
380
+ };
381
+ }).orchestrator = {
382
+ config: {
383
+ ...makeConfig(),
384
+ qmdColdCollection: "test-memory-cold",
385
+ },
386
+ async getStorage() {
387
+ return storage;
388
+ },
389
+ };
390
+
391
+ const result = await (service as unknown as {
392
+ serializeRecallResults(
393
+ snapshot: unknown,
394
+ disclosure: "summary",
395
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
396
+ }).serializeRecallResults(
397
+ {
398
+ sessionKey: "session-1",
399
+ recordedAt: "2026-06-16T12:00:00.000Z",
400
+ queryHash: "hash",
401
+ queryLen: 4,
402
+ memoryIds: [],
403
+ namespace: "default",
404
+ resultPaths: ["test-memory-cold/facts/2026-06-16/fact-001.md"],
405
+ },
406
+ "summary",
407
+ );
408
+
409
+ assert.equal(result.length, 1);
410
+ assert.equal(result[0].id, "fact-001");
411
+ assert.equal(result[0].path, coldMemoryPath);
412
+ assert.ok(result[0].preview.includes("Cold namespace recall content"));
413
+ assert.ok(readCalls.includes(coldMemoryPath));
414
+ assert.ok(
415
+ !readCalls.includes(path.join(memoryRoot, "test-memory-cold", "facts", "2026-06-16", "fact-001.md")),
416
+ "expected cold collection path to resolve under cold/ rather than a collection-named subdirectory",
417
+ );
418
+ });
419
+
420
+ test("last recall serialization propagates locked namespace collection errors", async () => {
421
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
422
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-lock-"));
423
+ const teamDir = path.join(
424
+ memoryRoot,
425
+ "namespaces",
426
+ namespaceIdentityToken("team"),
427
+ );
428
+ const storage = {
429
+ dir: memoryRoot,
430
+ async readMemoryByPath() {
431
+ return null;
432
+ },
433
+ async getMemoryById() {
434
+ return null;
435
+ },
436
+ } as unknown as StorageManager;
437
+ const teamStorage = {
438
+ dir: teamDir,
439
+ async readMemoryByPath() {
440
+ throw new SecureStoreLockedError("locked namespace store");
441
+ },
442
+ async getMemoryById() {
443
+ return null;
444
+ },
445
+ } as unknown as StorageManager;
446
+
447
+ (service as unknown as {
448
+ orchestrator: {
449
+ config: PluginConfig;
450
+ getStorage(namespace: string): Promise<StorageManager>;
451
+ };
452
+ }).orchestrator = {
453
+ config: makeConfig(),
454
+ async getStorage(namespace: string) {
455
+ return namespace === "team" ? teamStorage : storage;
456
+ },
457
+ };
458
+
459
+ const collection = namespaceCollectionName("test-memory", "team", {
460
+ defaultNamespace: "default",
461
+ useLegacyDefaultCollection: false,
462
+ });
463
+
464
+ await assert.rejects(
465
+ async () =>
466
+ await (service as unknown as {
467
+ serializeRecallResults(
468
+ snapshot: unknown,
469
+ disclosure: "summary",
470
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
471
+ }).serializeRecallResults(
472
+ {
473
+ sessionKey: "session-1",
474
+ recordedAt: "2026-06-16T12:00:00.000Z",
475
+ queryHash: "hash",
476
+ queryLen: 4,
477
+ memoryIds: [],
478
+ namespace: "default",
479
+ resultPaths: [`${collection}/2026-06-16/fact-001.md`],
480
+ },
481
+ "summary",
482
+ ),
483
+ SecureStoreLockedError,
484
+ );
485
+ });
486
+
487
+ test("last recall serialization does not treat date paths as collection prefixes", async () => {
488
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
489
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-date-miss-"));
490
+ const rootMemoryPath = path.join(memoryRoot, "fact-001.md");
491
+ const rootMemory = {
492
+ path: rootMemoryPath,
493
+ frontmatter: {
494
+ id: "fact-001",
495
+ created: "2026-06-16T12:00:00.000Z",
496
+ updated: "2026-06-16T12:00:00.000Z",
497
+ category: "fact",
498
+ status: "active",
499
+ },
500
+ content: "Root basename content should not be reused.",
501
+ };
502
+ const readCalls: string[] = [];
503
+ const storage = {
504
+ dir: memoryRoot,
505
+ async readMemoryByPath(filePath: string) {
506
+ readCalls.push(filePath);
507
+ return filePath === rootMemoryPath ? rootMemory : null;
508
+ },
509
+ async getMemoryById() {
510
+ return null;
511
+ },
512
+ } as unknown as StorageManager;
513
+
514
+ (service as unknown as {
515
+ orchestrator: {
516
+ config: PluginConfig;
517
+ getStorage(namespace: string): Promise<StorageManager>;
518
+ };
519
+ }).orchestrator = {
520
+ config: makeConfig(),
521
+ async getStorage() {
522
+ return storage;
523
+ },
524
+ };
525
+
526
+ const result = await (service as unknown as {
527
+ serializeRecallResults(
528
+ snapshot: unknown,
529
+ disclosure: "summary",
530
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
531
+ }).serializeRecallResults(
532
+ {
533
+ sessionKey: "session-1",
534
+ recordedAt: "2026-06-16T12:00:00.000Z",
535
+ queryHash: "hash",
536
+ queryLen: 4,
537
+ memoryIds: [],
538
+ namespace: "default",
539
+ resultPaths: ["2026-06-16/fact-001.md"],
540
+ },
541
+ "summary",
542
+ );
543
+
544
+ assert.deepEqual(result, []);
545
+ assert.ok(
546
+ !readCalls.includes(rootMemoryPath),
547
+ "expected date-relative miss not to probe storage root basename",
548
+ );
549
+ });
550
+
551
+ test("last recall serialization does not strip invalid collection prefixes", async () => {
552
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
553
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-invalid-prefix-"));
554
+ const defaultMemoryPath = path.join(
555
+ memoryRoot,
556
+ "facts",
557
+ "2026-06-16",
558
+ "fact-001.md",
559
+ );
560
+ const defaultMemory = {
561
+ path: defaultMemoryPath,
562
+ frontmatter: {
563
+ id: "fact-001",
564
+ created: "2026-06-16T12:00:00.000Z",
565
+ updated: "2026-06-16T12:00:00.000Z",
566
+ category: "fact",
567
+ status: "active",
568
+ },
569
+ content: "Default namespace content should not be reused.",
570
+ };
571
+ const readCalls: string[] = [];
572
+ const storage = {
573
+ dir: memoryRoot,
574
+ async readMemoryByPath(filePath: string) {
575
+ readCalls.push(filePath);
576
+ return filePath === defaultMemoryPath ? defaultMemory : null;
577
+ },
578
+ async getMemoryById() {
579
+ return null;
580
+ },
581
+ } as unknown as StorageManager;
582
+
583
+ (service as unknown as {
584
+ orchestrator: {
585
+ config: PluginConfig;
586
+ getStorage(namespace: string): Promise<StorageManager>;
587
+ };
588
+ }).orchestrator = {
589
+ config: makeConfig(),
590
+ async getStorage() {
591
+ return storage;
592
+ },
593
+ };
594
+
595
+ const result = await (service as unknown as {
596
+ serializeRecallResults(
597
+ snapshot: unknown,
598
+ disclosure: "summary",
599
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
600
+ }).serializeRecallResults(
601
+ {
602
+ sessionKey: "session-1",
603
+ recordedAt: "2026-06-16T12:00:00.000Z",
604
+ queryHash: "hash",
605
+ queryLen: 4,
606
+ memoryIds: [],
607
+ namespace: "default",
608
+ resultPaths: ["test-memory--not-a-token/2026-06-16/fact-001.md"],
609
+ },
610
+ "summary",
611
+ );
612
+
613
+ assert.deepEqual(result, []);
614
+ assert.ok(
615
+ !readCalls.includes(defaultMemoryPath),
616
+ "expected invalid collection prefix not to probe stripped default path",
617
+ );
618
+ });
619
+
620
+ test("last recall serialization preserves absolute paths from readable namespace storage", async () => {
621
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
622
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-cross-ns-"));
623
+ const teamDir = path.join(
624
+ memoryRoot,
625
+ "namespaces",
626
+ namespaceIdentityToken("team"),
627
+ );
628
+ const sharedDir = path.join(
629
+ memoryRoot,
630
+ "namespaces",
631
+ namespaceIdentityToken("shared"),
632
+ );
633
+ const sharedMemoryPath = path.join(
634
+ sharedDir,
635
+ "facts",
636
+ "2026-06-16",
637
+ "fact-shared.md",
638
+ );
639
+ const sharedMemory = {
640
+ path: sharedMemoryPath,
641
+ frontmatter: {
642
+ id: "fact-shared",
643
+ created: "2026-06-16T12:00:00.000Z",
644
+ updated: "2026-06-16T12:00:00.000Z",
645
+ category: "fact",
646
+ status: "active",
647
+ },
648
+ content: "Shared namespace content should survive serialization.",
649
+ };
650
+ const readCalls: Array<{ namespace: string; path: string }> = [];
651
+ const defaultStorage = {
652
+ dir: memoryRoot,
653
+ async readMemoryByPath(filePath: string) {
654
+ readCalls.push({ namespace: "default", path: filePath });
655
+ return null;
656
+ },
657
+ async getMemoryById() {
658
+ return null;
659
+ },
660
+ } as unknown as StorageManager;
661
+ const teamStorage = {
662
+ dir: teamDir,
663
+ async readMemoryByPath(filePath: string) {
664
+ readCalls.push({ namespace: "team", path: filePath });
665
+ return null;
666
+ },
667
+ async getMemoryById() {
668
+ return null;
669
+ },
670
+ } as unknown as StorageManager;
671
+ const sharedStorage = {
672
+ dir: sharedDir,
673
+ async readMemoryByPath(filePath: string) {
674
+ readCalls.push({ namespace: "shared", path: filePath });
675
+ return filePath === sharedMemoryPath ? sharedMemory : null;
676
+ },
677
+ async getMemoryById() {
678
+ return null;
679
+ },
680
+ } as unknown as StorageManager;
681
+
682
+ (service as unknown as {
683
+ orchestrator: {
684
+ config: PluginConfig;
685
+ getStorage(namespace: string): Promise<StorageManager>;
686
+ };
687
+ }).orchestrator = {
688
+ config: makeConfig(),
689
+ async getStorage(namespace: string) {
690
+ if (namespace === "team") return teamStorage;
691
+ if (namespace === "shared") return sharedStorage;
692
+ return defaultStorage;
693
+ },
694
+ };
695
+
696
+ const result = await (service as unknown as {
697
+ serializeRecallResults(
698
+ snapshot: unknown,
699
+ disclosure: "summary",
700
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
701
+ }).serializeRecallResults(
702
+ {
703
+ sessionKey: "session-1",
704
+ recordedAt: "2026-06-16T12:00:00.000Z",
705
+ queryHash: "hash",
706
+ queryLen: 4,
707
+ memoryIds: [],
708
+ namespace: "team",
709
+ resultPaths: [sharedMemoryPath],
710
+ },
711
+ "summary",
712
+ );
713
+
714
+ assert.equal(result.length, 1);
715
+ assert.equal(result[0].id, "fact-shared");
716
+ assert.equal(result[0].path, sharedMemoryPath);
717
+ assert.deepEqual(readCalls, [{ namespace: "shared", path: sharedMemoryPath }]);
718
+ });
719
+
720
+ test("last recall serialization preserves absolute paths from dynamic namespace storage", async () => {
721
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
722
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-dynamic-ns-"));
723
+ const dynamicNamespace = "team-project-alpha";
724
+ const dynamicDir = path.join(
725
+ memoryRoot,
726
+ "namespaces",
727
+ namespaceIdentityToken(dynamicNamespace),
728
+ );
729
+ const dynamicMemoryPath = path.join(
730
+ dynamicDir,
731
+ "facts",
732
+ "2026-06-16",
733
+ "fact-dynamic.md",
734
+ );
735
+ const dynamicMemory = {
736
+ path: dynamicMemoryPath,
737
+ frontmatter: {
738
+ id: "fact-dynamic",
739
+ created: "2026-06-16T12:00:00.000Z",
740
+ updated: "2026-06-16T12:00:00.000Z",
741
+ category: "fact",
742
+ status: "active",
743
+ },
744
+ content: "Dynamic namespace content should survive serialization.",
745
+ };
746
+ const readCalls: Array<{ namespace: string; path: string }> = [];
747
+ const defaultStorage = {
748
+ dir: memoryRoot,
749
+ async readMemoryByPath(filePath: string) {
750
+ readCalls.push({ namespace: "default", path: filePath });
751
+ return null;
752
+ },
753
+ async getMemoryById() {
754
+ return null;
755
+ },
756
+ } as unknown as StorageManager;
757
+ const dynamicStorage = {
758
+ dir: dynamicDir,
759
+ async readMemoryByPath(filePath: string) {
760
+ readCalls.push({ namespace: dynamicNamespace, path: filePath });
761
+ return filePath === dynamicMemoryPath ? dynamicMemory : null;
762
+ },
763
+ async getMemoryById() {
764
+ return null;
765
+ },
766
+ } as unknown as StorageManager;
767
+
768
+ (service as unknown as {
769
+ orchestrator: {
770
+ config: PluginConfig;
771
+ getStorage(namespace: string): Promise<StorageManager>;
772
+ };
773
+ }).orchestrator = {
774
+ config: { ...makeConfig(), memoryDir: memoryRoot },
775
+ async getStorage(namespace: string) {
776
+ return namespace === dynamicNamespace ? dynamicStorage : defaultStorage;
777
+ },
778
+ };
779
+
780
+ const result = await (service as unknown as {
781
+ serializeRecallResults(
782
+ snapshot: unknown,
783
+ disclosure: "summary",
784
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
785
+ }).serializeRecallResults(
786
+ {
787
+ sessionKey: "session-1",
788
+ recordedAt: "2026-06-16T12:00:00.000Z",
789
+ queryHash: "hash",
790
+ queryLen: 4,
791
+ memoryIds: [],
792
+ namespace: "team",
793
+ resultPaths: [dynamicMemoryPath],
794
+ },
795
+ "summary",
796
+ );
797
+
798
+ assert.equal(result.length, 1);
799
+ assert.equal(result[0].id, "fact-dynamic");
800
+ assert.deepEqual(readCalls, [
801
+ { namespace: dynamicNamespace, path: dynamicMemoryPath },
802
+ ]);
803
+ });
804
+
805
+ test("last recall serialization rejects traversing collection paths", async () => {
806
+ const service = Object.create(EngramAccessService.prototype) as EngramAccessService;
807
+ const memoryRoot = await mkdtemp(path.join(os.tmpdir(), "remnic-access-qmd-traversal-"));
808
+ const defaultMemoryPath = path.join(
809
+ memoryRoot,
810
+ "facts",
811
+ "2026-06-16",
812
+ "fact-001.md",
813
+ );
814
+ const defaultMemory = {
815
+ path: defaultMemoryPath,
816
+ frontmatter: {
817
+ id: "fact-001",
818
+ created: "2026-06-16T12:00:00.000Z",
819
+ updated: "2026-06-16T12:00:00.000Z",
820
+ category: "fact",
821
+ status: "active",
822
+ },
823
+ content: "Default namespace content should not be reused.",
824
+ };
825
+ const teamDir = path.join(
826
+ memoryRoot,
827
+ "namespaces",
828
+ namespaceIdentityToken("team"),
829
+ );
830
+ const readCalls: Array<{ namespace: string; path: string }> = [];
831
+ const storage = {
832
+ dir: memoryRoot,
833
+ async readMemoryByPath(filePath: string) {
834
+ readCalls.push({ namespace: "default", path: filePath });
835
+ return filePath === defaultMemoryPath ? defaultMemory : null;
836
+ },
837
+ async getMemoryById() {
838
+ return null;
839
+ },
840
+ } as unknown as StorageManager;
841
+ const teamStorage = {
842
+ dir: teamDir,
843
+ async readMemoryByPath(filePath: string) {
844
+ readCalls.push({ namespace: "team", path: filePath });
845
+ return filePath === defaultMemoryPath ? defaultMemory : null;
846
+ },
847
+ async getMemoryById() {
848
+ return null;
849
+ },
850
+ } as unknown as StorageManager;
851
+
852
+ (service as unknown as {
853
+ orchestrator: {
854
+ config: PluginConfig;
855
+ getStorage(namespace: string): Promise<StorageManager>;
856
+ };
857
+ }).orchestrator = {
858
+ config: makeConfig(),
859
+ async getStorage(namespace: string) {
860
+ return namespace === "team" ? teamStorage : storage;
861
+ },
862
+ };
863
+
864
+ const collection = namespaceCollectionName("test-memory", "team", {
865
+ defaultNamespace: "default",
866
+ useLegacyDefaultCollection: false,
867
+ });
868
+ const result = await (service as unknown as {
869
+ serializeRecallResults(
870
+ snapshot: unknown,
871
+ disclosure: "summary",
872
+ ): Promise<Array<{ id: string; path: string; preview: string; status: string }>>;
873
+ }).serializeRecallResults(
874
+ {
875
+ sessionKey: "session-1",
876
+ recordedAt: "2026-06-16T12:00:00.000Z",
877
+ queryHash: "hash",
878
+ queryLen: 4,
879
+ memoryIds: [],
880
+ namespace: "default",
881
+ resultPaths: [`${collection}/../../facts/2026-06-16/fact-001.md`],
882
+ },
883
+ "summary",
884
+ );
885
+
886
+ assert.deepEqual(result, []);
887
+ assert.ok(
888
+ !readCalls.some((call) => call.path === defaultMemoryPath),
889
+ "expected traversing collection path not to probe escaped default path",
890
+ );
891
+ });
892
+
153
893
  test("memorySearch without an explicit namespace uses readable recall namespaces", async () => {
154
894
  const { service } = makeService();
155
895
  let searchParams: unknown;