@remnic/core 9.3.713 → 9.3.715

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 (325) hide show
  1. package/dist/access-boundary.d.ts +6 -6
  2. package/dist/access-boundary.js +17 -16
  3. package/dist/access-cli.js +39 -38
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +5 -5
  6. package/dist/access-http.js +23 -22
  7. package/dist/access-mcp.d.ts +12 -5
  8. package/dist/access-mcp.js +20 -19
  9. package/dist/access-operations-batch.js +18 -17
  10. package/dist/access-operations.d.ts +6 -5
  11. package/dist/access-operations.js +19 -18
  12. package/dist/{access-service-DwVmvgBg.d.ts → access-service-GgnA--CE.d.ts} +12 -4
  13. package/dist/access-service.d.ts +5 -5
  14. package/dist/access-service.js +16 -15
  15. package/dist/access-surface-catalog.d.ts +5 -5
  16. package/dist/access-surface-catalog.js +6 -1
  17. package/dist/access-surface-catalog.js.map +1 -1
  18. package/dist/action-confidence.d.ts +1 -1
  19. package/dist/active-memory-bridge.d.ts +3 -1
  20. package/dist/active-memory-bridge.js +2 -1
  21. package/dist/active-recall.d.ts +1 -1
  22. package/dist/active-recall.js +4 -3
  23. package/dist/active-recall.js.map +1 -1
  24. package/dist/adapters/index.js +4 -4
  25. package/dist/adapters/registry.js +2 -2
  26. package/dist/behavior-learner.d.ts +1 -1
  27. package/dist/behavior-signals.d.ts +1 -1
  28. package/dist/bootstrap.d.ts +4 -4
  29. package/dist/briefing.d.ts +1 -1
  30. package/dist/briefing.js +8 -7
  31. package/dist/buffer-surprise-report.d.ts +1 -1
  32. package/dist/buffer.d.ts +1 -1
  33. package/dist/calibration.d.ts +1 -1
  34. package/dist/capabilities.d.ts +1 -1
  35. package/dist/{catalog-CadPvH29.d.ts → catalog-CbR0CsUw.d.ts} +1 -1
  36. package/dist/causal-behavior.d.ts +1 -1
  37. package/dist/causal-consolidation.d.ts +1 -1
  38. package/dist/causal-consolidation.js +9 -8
  39. package/dist/causal-consolidation.js.map +1 -1
  40. package/dist/{chunk-OMSTU233.js → chunk-2KAYTPPT.js} +4 -4
  41. package/dist/{chunk-VYZNWH4J.js → chunk-2SXMCQEQ.js} +3 -3
  42. package/dist/{chunk-NXL5CVE7.js → chunk-2Y6LMOQQ.js} +2 -2
  43. package/dist/{chunk-ZDUF7K5V.js → chunk-3VUPWDSE.js} +15 -3
  44. package/dist/{chunk-ZDUF7K5V.js.map → chunk-3VUPWDSE.js.map} +1 -1
  45. package/dist/{chunk-FVQJYWH7.js → chunk-5GKPFL3S.js} +1 -1
  46. package/dist/{chunk-FVQJYWH7.js.map → chunk-5GKPFL3S.js.map} +1 -1
  47. package/dist/{chunk-LQ4J7ELC.js → chunk-67HG7KFE.js} +2 -2
  48. package/dist/{chunk-ZBG4K36I.js → chunk-6FUJ2VYY.js} +3 -3
  49. package/dist/{chunk-GMRNKPWO.js → chunk-6QUPUTT7.js} +2 -2
  50. package/dist/{chunk-Z56IHRVV.js → chunk-6UU43ZGD.js} +2 -2
  51. package/dist/{chunk-APJQ6UEA.js → chunk-AGNBY3VG.js} +4 -4
  52. package/dist/{chunk-OWOKOFXK.js → chunk-AJOIM6UR.js} +2 -2
  53. package/dist/{chunk-JBPKEARU.js → chunk-AU7Q3LSC.js} +4 -4
  54. package/dist/{chunk-UHN2TNSB.js → chunk-BNOAB5HH.js} +38 -11
  55. package/dist/chunk-BNOAB5HH.js.map +1 -0
  56. package/dist/{chunk-VW24K2Q4.js → chunk-CTAHKIG6.js} +169 -8
  57. package/dist/chunk-CTAHKIG6.js.map +1 -0
  58. package/dist/{chunk-K22IJO4R.js → chunk-CTOQEZSN.js} +2 -2
  59. package/dist/{chunk-SINGJCUR.js → chunk-CX77GNMB.js} +14 -3
  60. package/dist/chunk-CX77GNMB.js.map +1 -0
  61. package/dist/{chunk-HSDJCT3V.js → chunk-DXGS5YOQ.js} +3 -3
  62. package/dist/{chunk-HV57RHMD.js → chunk-EH5ED3C6.js} +2 -2
  63. package/dist/{chunk-7NDYFAJS.js → chunk-GM3BMWKR.js} +2 -2
  64. package/dist/{chunk-RMT7PAVW.js → chunk-HHLWSWWF.js} +2 -2
  65. package/dist/chunk-HHLWSWWF.js.map +1 -0
  66. package/dist/{chunk-5QUS24F7.js → chunk-I56LKMF7.js} +2 -2
  67. package/dist/{chunk-VUNI6Y3D.js → chunk-IHMT6XTY.js} +8 -4
  68. package/dist/chunk-IHMT6XTY.js.map +1 -0
  69. package/dist/chunk-JAKIDQB2.js +173 -0
  70. package/dist/chunk-JAKIDQB2.js.map +1 -0
  71. package/dist/{chunk-35YJ6KCV.js → chunk-JEIROMLX.js} +2 -2
  72. package/dist/{chunk-SKQCFAYU.js → chunk-JVEMUX6L.js} +2 -2
  73. package/dist/{chunk-CXMXAC5R.js → chunk-K44MIN6D.js} +3 -3
  74. package/dist/{chunk-JC3MIKR4.js → chunk-MECU6WSH.js} +188 -31
  75. package/dist/chunk-MECU6WSH.js.map +1 -0
  76. package/dist/{chunk-BQCFXAMN.js → chunk-MPHDVHIB.js} +2 -2
  77. package/dist/{chunk-BOGENF7P.js → chunk-MSVSP5VO.js} +1 -1
  78. package/dist/chunk-MSVSP5VO.js.map +1 -0
  79. package/dist/{chunk-QXNFQKWU.js → chunk-MTHNJCOJ.js} +2 -2
  80. package/dist/{chunk-3TCRU4JA.js → chunk-O62P2LFL.js} +2 -2
  81. package/dist/{chunk-JSDZMOT7.js → chunk-OC56UWV5.js} +11 -11
  82. package/dist/{chunk-7IBEWQLG.js → chunk-QOIONSOI.js} +2 -2
  83. package/dist/{chunk-4P5UAL3C.js → chunk-RBHANGVX.js} +6 -6
  84. package/dist/{chunk-SK2CR6MW.js → chunk-RVLB4E6N.js} +2 -2
  85. package/dist/{chunk-DJNKN3XY.js → chunk-SYDHFFAW.js} +1084 -12
  86. package/dist/chunk-SYDHFFAW.js.map +1 -0
  87. package/dist/{chunk-VILEUJXC.js → chunk-UC4YOAC2.js} +74 -2
  88. package/dist/{chunk-VILEUJXC.js.map → chunk-UC4YOAC2.js.map} +1 -1
  89. package/dist/{chunk-CNVIWMQI.js → chunk-UY4JMEAK.js} +2 -2
  90. package/dist/{chunk-S6FQLQGH.js → chunk-V7GDTQ6I.js} +2 -2
  91. package/dist/{chunk-JNOYYWCA.js → chunk-VO4UICII.js} +3 -3
  92. package/dist/{chunk-54TI5GLV.js → chunk-WI4QX7GH.js} +3 -3
  93. package/dist/{chunk-3XHD3XGK.js → chunk-XCTDHF7U.js} +30 -2
  94. package/dist/chunk-XCTDHF7U.js.map +1 -0
  95. package/dist/{chunk-XKU4YE6Z.js → chunk-XZTUMWKQ.js} +2 -2
  96. package/dist/{chunk-GKPIY7EQ.js → chunk-YUJL27ET.js} +160 -61
  97. package/dist/chunk-YUJL27ET.js.map +1 -0
  98. package/dist/{cli-DfDMJqPP.d.ts → cli-Do1YtfnH.d.ts} +3 -3
  99. package/dist/cli.d.ts +6 -6
  100. package/dist/cli.js +42 -41
  101. package/dist/compounding/engine.d.ts +1 -1
  102. package/dist/compounding/engine.js +8 -7
  103. package/dist/compounding/preference-consolidator.d.ts +1 -1
  104. package/dist/compression-optimizer.d.ts +1 -1
  105. package/dist/config.d.ts +1 -1
  106. package/dist/config.js +4 -3
  107. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  108. package/dist/connectors/codex-materialize-runner.js +8 -7
  109. package/dist/connectors/codex-materialize.d.ts +1 -1
  110. package/dist/connectors/index.d.ts +1 -1
  111. package/dist/connectors/index.js +9 -8
  112. package/dist/consolidation-provenance-check.d.ts +1 -1
  113. package/dist/consolidation-undo.d.ts +1 -1
  114. package/dist/contradiction/index.d.ts +1 -1
  115. package/dist/conversation-index/backend.d.ts +1 -1
  116. package/dist/conversation-index/chunker.d.ts +1 -1
  117. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  118. package/dist/conversation-index/indexer.d.ts +1 -1
  119. package/dist/conversation-index/search.d.ts +1 -1
  120. package/dist/day-summary.d.ts +1 -1
  121. package/dist/delinearize.d.ts +1 -1
  122. package/dist/direct-answer-wiring.d.ts +1 -1
  123. package/dist/direct-answer.d.ts +1 -1
  124. package/dist/embedding-fallback.d.ts +1 -1
  125. package/dist/enrichment/index.d.ts +1 -1
  126. package/dist/entity-retrieval.d.ts +1 -1
  127. package/dist/entity-retrieval.js +8 -7
  128. package/dist/entity-schema.d.ts +1 -1
  129. package/dist/explicit-capture.d.ts +4 -4
  130. package/dist/explicit-capture.js +3 -2
  131. package/dist/extraction-faithfulness.d.ts +1 -1
  132. package/dist/extraction-judge-telemetry.d.ts +1 -1
  133. package/dist/extraction-judge-training.d.ts +1 -1
  134. package/dist/extraction-judge.d.ts +1 -1
  135. package/dist/extraction.d.ts +1 -1
  136. package/dist/extraction.js +4 -3
  137. package/dist/fallback-llm.d.ts +1 -1
  138. package/dist/identity-continuity.d.ts +1 -1
  139. package/dist/importance.d.ts +1 -1
  140. package/dist/index.d.ts +9 -9
  141. package/dist/index.js +61 -60
  142. package/dist/index.js.map +1 -1
  143. package/dist/intent.d.ts +1 -1
  144. package/dist/lcm/engine.d.ts +1 -1
  145. package/dist/lcm/index.d.ts +1 -1
  146. package/dist/lcm/index.js +3 -3
  147. package/dist/lcm/tools.d.ts +1 -1
  148. package/dist/lifecycle.d.ts +1 -1
  149. package/dist/live-connectors-runner.d.ts +1 -1
  150. package/dist/local-llm.d.ts +1 -1
  151. package/dist/maintenance/memory-governance.d.ts +1 -1
  152. package/dist/maintenance/memory-governance.js +8 -7
  153. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -7
  154. package/dist/maintenance/rebuild-memory-projection.js +9 -8
  155. package/dist/mcp-memory-inspector-app.d.ts +5 -5
  156. package/dist/memory-action-policy.d.ts +1 -1
  157. package/dist/memory-cache.d.ts +1 -1
  158. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  159. package/dist/memory-projection-store.d.ts +1 -1
  160. package/dist/memory-provenance.d.ts +1 -1
  161. package/dist/memory-worth-outcomes.d.ts +1 -1
  162. package/dist/models-json.d.ts +1 -1
  163. package/dist/namespaces/migrate.d.ts +2 -2
  164. package/dist/namespaces/migrate.js +12 -11
  165. package/dist/namespaces/principal.d.ts +1 -1
  166. package/dist/namespaces/search.d.ts +1 -1
  167. package/dist/namespaces/search.js +3 -3
  168. package/dist/namespaces/storage.d.ts +2 -2
  169. package/dist/namespaces/storage.js +8 -7
  170. package/dist/native-knowledge.d.ts +1 -1
  171. package/dist/operator-toolkit.d.ts +1 -1
  172. package/dist/operator-toolkit.js +17 -16
  173. package/dist/orchestration/maintenance.d.ts +2 -2
  174. package/dist/orchestration/maintenance.js +10 -9
  175. package/dist/{orchestrator-B1iVjEyc.d.ts → orchestrator-BOaVstFG.d.ts} +32 -4
  176. package/dist/orchestrator.d.ts +4 -4
  177. package/dist/orchestrator.js +32 -31
  178. package/dist/patterns-cli.d.ts +1 -1
  179. package/dist/policy-runtime.d.ts +1 -1
  180. package/dist/provenance.d.ts +1 -1
  181. package/dist/provenance.js +3 -2
  182. package/dist/qmd-recall-cache.d.ts +1 -1
  183. package/dist/qmd.d.ts +1 -1
  184. package/dist/recall-disclosure-escalation.d.ts +1 -1
  185. package/dist/recall-explain-renderer.d.ts +1 -1
  186. package/dist/recall-explain-renderer.js +3 -3
  187. package/dist/recall-handles.d.ts +228 -0
  188. package/dist/recall-handles.js +42 -0
  189. package/dist/recall-handles.js.map +1 -0
  190. package/dist/recall-planner-llm.d.ts +1 -1
  191. package/dist/recall-state.d.ts +40 -2
  192. package/dist/recall-state.js +3 -1
  193. package/dist/recall-tag-filter.d.ts +1 -1
  194. package/dist/recall-xray-cli.d.ts +1 -1
  195. package/dist/recall-xray-cli.js +4 -4
  196. package/dist/recall-xray-renderer.d.ts +1 -1
  197. package/dist/recall-xray-renderer.js +3 -3
  198. package/dist/recall-xray.d.ts +1 -1
  199. package/dist/recall-xray.js +2 -2
  200. package/dist/resolve-auth-token.d.ts +1 -1
  201. package/dist/resume-bundles.js +5 -4
  202. package/dist/retrieval-agents.d.ts +1 -1
  203. package/dist/retrieval-tiers.d.ts +1 -1
  204. package/dist/routing/engine.d.ts +1 -1
  205. package/dist/routing/store.d.ts +1 -1
  206. package/dist/sanitize.d.ts +2 -0
  207. package/dist/sanitize.js +6 -2
  208. package/dist/schemas.d.ts +22 -22
  209. package/dist/search/embed-helper.d.ts +1 -1
  210. package/dist/search/factory.d.ts +1 -1
  211. package/dist/search/factory.js +2 -2
  212. package/dist/search/index.d.ts +1 -1
  213. package/dist/search/index.js +4 -4
  214. package/dist/search/lancedb-backend.d.ts +1 -1
  215. package/dist/search/meilisearch-backend.d.ts +1 -1
  216. package/dist/search/noop-backend.d.ts +1 -1
  217. package/dist/search/orama-backend.d.ts +1 -1
  218. package/dist/search/port.d.ts +1 -1
  219. package/dist/search/remote-backend.d.ts +1 -1
  220. package/dist/{semantic-consolidation-CY8uVRNJ.d.ts → semantic-consolidation-DSjMDZ1u.d.ts} +1 -1
  221. package/dist/semantic-consolidation.d.ts +2 -2
  222. package/dist/semantic-consolidation.js +9 -8
  223. package/dist/semantic-rule-promotion.js +8 -7
  224. package/dist/semantic-rule-verifier.d.ts +1 -1
  225. package/dist/semantic-rule-verifier.js +8 -7
  226. package/dist/session-observer-bands.d.ts +1 -1
  227. package/dist/session-observer-state.d.ts +1 -1
  228. package/dist/shared-context/manager.d.ts +3 -3
  229. package/dist/signal.d.ts +1 -1
  230. package/dist/storage.d.ts +1 -1
  231. package/dist/storage.js +7 -6
  232. package/dist/summarizer.d.ts +1 -1
  233. package/dist/summary-snapshot.d.ts +1 -1
  234. package/dist/temporal-supersession.d.ts +1 -1
  235. package/dist/temporal-validity.d.ts +1 -1
  236. package/dist/threading.d.ts +1 -1
  237. package/dist/tier-migration.d.ts +1 -1
  238. package/dist/tier-routing.d.ts +1 -1
  239. package/dist/topics.d.ts +1 -1
  240. package/dist/transcript.d.ts +1 -1
  241. package/dist/transfer/import-sqlite.js +2 -2
  242. package/dist/transfer/types.d.ts +12 -12
  243. package/dist/{types-Dr0Cw3L9.d.ts → types-D9dwzU_x.d.ts} +25 -1
  244. package/dist/types.d.ts +1 -1
  245. package/dist/types.js +1 -1
  246. package/dist/utility-runtime.d.ts +1 -1
  247. package/dist/verified-recall.js +8 -7
  248. package/package.json +2 -2
  249. package/src/access-boundary.ts +4 -1
  250. package/src/access-http.ts +33 -1
  251. package/src/access-mcp.test.ts +28 -0
  252. package/src/access-mcp.ts +67 -2
  253. package/src/access-operations-batch.ts +14 -0
  254. package/src/access-operations.ts +5 -0
  255. package/src/access-service.ts +43 -2
  256. package/src/access-surface-catalog.test.ts +4 -2
  257. package/src/access-surface-catalog.ts +5 -0
  258. package/src/active-memory-bridge.test.ts +72 -0
  259. package/src/active-memory-bridge.ts +21 -2
  260. package/src/chat/chat-cli.test.ts +142 -0
  261. package/src/chat/chat-cli.ts +206 -0
  262. package/src/chat/chat-config.ts +57 -0
  263. package/src/chat/chat-engine.test.ts +272 -0
  264. package/src/chat/chat-engine.ts +518 -0
  265. package/src/chat/chat-executor.ts +133 -0
  266. package/src/chat/chat-factory.ts +161 -0
  267. package/src/chat/chat-http.test.ts +197 -0
  268. package/src/chat/chat-http.ts +222 -0
  269. package/src/chat/chat-llm.ts +229 -0
  270. package/src/chat/chat-mcp.test.ts +135 -0
  271. package/src/chat/chat-security.test.ts +491 -0
  272. package/src/chat/chat-session.ts +296 -0
  273. package/src/chat/chat-system-prompt.ts +76 -0
  274. package/src/chat/chat-tools.ts +255 -0
  275. package/src/chat/chat-types.ts +167 -0
  276. package/src/cli.ts +20 -0
  277. package/src/config.ts +9 -0
  278. package/src/faithfulness-graph-guard.test.ts +214 -8
  279. package/src/orchestrator.ts +167 -22
  280. package/src/recall-handles-wiring.test.ts +477 -0
  281. package/src/recall-handles.test.ts +283 -0
  282. package/src/recall-handles.ts +414 -0
  283. package/src/recall-state.ts +99 -0
  284. package/src/sanitize.ts +6 -0
  285. package/src/types.ts +29 -0
  286. package/dist/chunk-3XHD3XGK.js.map +0 -1
  287. package/dist/chunk-BOGENF7P.js.map +0 -1
  288. package/dist/chunk-DJNKN3XY.js.map +0 -1
  289. package/dist/chunk-GKPIY7EQ.js.map +0 -1
  290. package/dist/chunk-JC3MIKR4.js.map +0 -1
  291. package/dist/chunk-RMT7PAVW.js.map +0 -1
  292. package/dist/chunk-SINGJCUR.js.map +0 -1
  293. package/dist/chunk-UHN2TNSB.js.map +0 -1
  294. package/dist/chunk-VUNI6Y3D.js.map +0 -1
  295. package/dist/chunk-VW24K2Q4.js.map +0 -1
  296. /package/dist/{chunk-OMSTU233.js.map → chunk-2KAYTPPT.js.map} +0 -0
  297. /package/dist/{chunk-VYZNWH4J.js.map → chunk-2SXMCQEQ.js.map} +0 -0
  298. /package/dist/{chunk-NXL5CVE7.js.map → chunk-2Y6LMOQQ.js.map} +0 -0
  299. /package/dist/{chunk-LQ4J7ELC.js.map → chunk-67HG7KFE.js.map} +0 -0
  300. /package/dist/{chunk-ZBG4K36I.js.map → chunk-6FUJ2VYY.js.map} +0 -0
  301. /package/dist/{chunk-GMRNKPWO.js.map → chunk-6QUPUTT7.js.map} +0 -0
  302. /package/dist/{chunk-Z56IHRVV.js.map → chunk-6UU43ZGD.js.map} +0 -0
  303. /package/dist/{chunk-APJQ6UEA.js.map → chunk-AGNBY3VG.js.map} +0 -0
  304. /package/dist/{chunk-OWOKOFXK.js.map → chunk-AJOIM6UR.js.map} +0 -0
  305. /package/dist/{chunk-JBPKEARU.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  306. /package/dist/{chunk-K22IJO4R.js.map → chunk-CTOQEZSN.js.map} +0 -0
  307. /package/dist/{chunk-HSDJCT3V.js.map → chunk-DXGS5YOQ.js.map} +0 -0
  308. /package/dist/{chunk-HV57RHMD.js.map → chunk-EH5ED3C6.js.map} +0 -0
  309. /package/dist/{chunk-7NDYFAJS.js.map → chunk-GM3BMWKR.js.map} +0 -0
  310. /package/dist/{chunk-5QUS24F7.js.map → chunk-I56LKMF7.js.map} +0 -0
  311. /package/dist/{chunk-35YJ6KCV.js.map → chunk-JEIROMLX.js.map} +0 -0
  312. /package/dist/{chunk-SKQCFAYU.js.map → chunk-JVEMUX6L.js.map} +0 -0
  313. /package/dist/{chunk-CXMXAC5R.js.map → chunk-K44MIN6D.js.map} +0 -0
  314. /package/dist/{chunk-BQCFXAMN.js.map → chunk-MPHDVHIB.js.map} +0 -0
  315. /package/dist/{chunk-QXNFQKWU.js.map → chunk-MTHNJCOJ.js.map} +0 -0
  316. /package/dist/{chunk-3TCRU4JA.js.map → chunk-O62P2LFL.js.map} +0 -0
  317. /package/dist/{chunk-JSDZMOT7.js.map → chunk-OC56UWV5.js.map} +0 -0
  318. /package/dist/{chunk-7IBEWQLG.js.map → chunk-QOIONSOI.js.map} +0 -0
  319. /package/dist/{chunk-4P5UAL3C.js.map → chunk-RBHANGVX.js.map} +0 -0
  320. /package/dist/{chunk-SK2CR6MW.js.map → chunk-RVLB4E6N.js.map} +0 -0
  321. /package/dist/{chunk-CNVIWMQI.js.map → chunk-UY4JMEAK.js.map} +0 -0
  322. /package/dist/{chunk-S6FQLQGH.js.map → chunk-V7GDTQ6I.js.map} +0 -0
  323. /package/dist/{chunk-JNOYYWCA.js.map → chunk-VO4UICII.js.map} +0 -0
  324. /package/dist/{chunk-54TI5GLV.js.map → chunk-WI4QX7GH.js.map} +0 -0
  325. /package/dist/{chunk-XKU4YE6Z.js.map → chunk-XZTUMWKQ.js.map} +0 -0
@@ -126,6 +126,7 @@ import { RelevanceStore } from "./relevance.js";
126
126
  import { NegativeExampleStore } from "./negative.js";
127
127
  import {
128
128
  LastRecallStore,
129
+ RecallHandleHistoryStore,
129
130
  type LastRecallBudgetSummary,
130
131
  TierMigrationStatusStore,
131
132
  clampGraphRecallExpandedEntries,
@@ -134,6 +135,14 @@ import {
134
135
  type TierMigrationCycleSummary,
135
136
  type TierMigrationStatusSnapshot,
136
137
  } from "./recall-state.js";
138
+ import {
139
+ buildHandleIndexForResults,
140
+ MEMORY_ID_PATTERN,
141
+ parseIdOrHandle,
142
+ resolveHandle,
143
+ stripHandles,
144
+ type RecallSnapshotIds,
145
+ } from "./recall-handles.js";
137
146
  import {
138
147
  buildXraySnapshot,
139
148
  type RecallFilterTrace,
@@ -1722,8 +1731,16 @@ export function resolveRecentThreadMemoryPaths(options: {
1722
1731
  buildMemoryPathById(options.allMemsForGraph, options.storageDir);
1723
1732
  if (pathById.size === 0) return [];
1724
1733
 
1734
+ // #1635 (defensive): skip pending_review ids from legacy episode sets.
1735
+ const pendingReviewIds = new Set<string>(
1736
+ (options.allMemsForGraph ?? [])
1737
+ .filter((m) => m.frontmatter.status === "pending_review" && m.frontmatter.id)
1738
+ .map((m) => m.frontmatter.id as string),
1739
+ );
1740
+
1725
1741
  return options.threadEpisodeIds
1726
1742
  .filter((id) => id !== options.currentMemoryId)
1743
+ .filter((id) => !pendingReviewIds.has(id))
1727
1744
  .slice(-maxRecent)
1728
1745
  .map((id) => pathById.get(id))
1729
1746
  .filter((p): p is string => typeof p === "string" && p.length > 0);
@@ -1849,6 +1866,11 @@ export class Orchestrator {
1849
1866
  * callers already destructure `persistedIds` by position.
1850
1867
  */
1851
1868
  private lastPersistExtractionDeferredCount: number = 0;
1869
+ /**
1870
+ * Side-channel (#1635): pending_review persisted ids from the last
1871
+ * persistExtraction; runExtraction excludes them from the thread episode set.
1872
+ */
1873
+ private lastPersistExtractionPendingReviewIds: string[] = [];
1852
1874
  private readonly _fastGatewayLlm: FallbackLlmClient | null;
1853
1875
 
1854
1876
  get fastGatewayLlm(): FallbackLlmClient | null {
@@ -1872,6 +1894,7 @@ export class Orchestrator {
1872
1894
  readonly relevance: RelevanceStore;
1873
1895
  readonly negatives: NegativeExampleStore;
1874
1896
  readonly lastRecall: LastRecallStore;
1897
+ readonly handleHistory: RecallHandleHistoryStore;
1875
1898
  readonly tierMigrationStatus: TierMigrationStatusStore;
1876
1899
  /**
1877
1900
  * In-memory X-ray snapshot from the most recent `recall()` call that
@@ -2797,6 +2820,9 @@ export class Orchestrator {
2797
2820
  this.relevance = new RelevanceStore(config.memoryDir);
2798
2821
  this.negatives = new NegativeExampleStore(config.memoryDir);
2799
2822
  this.lastRecall = new LastRecallStore(config.memoryDir);
2823
+ this.handleHistory = new RecallHandleHistoryStore(config.memoryDir, {
2824
+ maxDepth: config.recallHandleSnapshotDepth,
2825
+ });
2800
2826
  this.tierMigrationStatus = new TierMigrationStatusStore(config.memoryDir);
2801
2827
  this.sessionObserver = new SessionObserverState({
2802
2828
  memoryDir: config.memoryDir,
@@ -3241,6 +3267,7 @@ export class Orchestrator {
3241
3267
  await this.relevance.load();
3242
3268
  await this.negatives.load();
3243
3269
  await this.lastRecall.load();
3270
+ await this.handleHistory.load();
3244
3271
  await this.tierMigrationStatus.load();
3245
3272
  await this.sessionObserver.load();
3246
3273
  this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();
@@ -11299,7 +11326,7 @@ export class Orchestrator {
11299
11326
  this.appendRecallSection(
11300
11327
  sectionBuckets,
11301
11328
  "workspace-context",
11302
- this.formatQmdResults("Workspace Context", globalResults),
11329
+ this.formatQmdResults("Workspace Context", globalResults, sessionKey),
11303
11330
  );
11304
11331
  }
11305
11332
 
@@ -12073,6 +12100,22 @@ export class Orchestrator {
12073
12100
  backendDegradations.length > 0 ? backendDegradations : undefined,
12074
12101
  })
12075
12102
  .catch((err) => log.debug(`last recall record failed: ${err}`));
12103
+ // Issue #1582 — record the admitted memory-id set for handle resolution.
12104
+ // Only when handles are enabled: if injection is off, no handle is ever
12105
+ // rendered, so there is nothing to resolve and we skip the write.
12106
+ if (this.config.recallMemoryHandles && recalledMemoryIds.length > 0) {
12107
+ // Only handle-eligible ids aid resolution; filter out non-memory .md
12108
+ // basenames (entity reconstructions) so the resolver never records a
12109
+ // citation target that cannot be loaded.
12110
+ const handleEligibleIds = recalledMemoryIds.filter((id) =>
12111
+ MEMORY_ID_PATTERN.test(id),
12112
+ );
12113
+ if (handleEligibleIds.length > 0) {
12114
+ this.handleHistory
12115
+ .record(sessionKey, handleEligibleIds)
12116
+ .catch((err) => log.debug(`handle history record failed: ${err}`));
12117
+ }
12118
+ }
12076
12119
  }
12077
12120
  if (sessionKey) {
12078
12121
  this.queueEvalShadowRecall({
@@ -12165,9 +12208,17 @@ export class Orchestrator {
12165
12208
  ? sessionKey
12166
12209
  : "default";
12167
12210
  const captureTimestamp = new Date().toISOString();
12211
+ // Issue #1582 hygiene §2 — strip any echoed `[m:xxxx]` handle before the
12212
+ // turn enters the extraction buffer so handles never become memory content
12213
+ // or get QMD-indexed (rule 23). Gated on the feature flag: when handles are
12214
+ // off none are ever injected, so there is nothing to strip and the buffer
12215
+ // stays byte-identical to the pre-#1582 path.
12216
+ const bufferedContent = this.config.recallMemoryHandles
12217
+ ? stripHandles(content)
12218
+ : content;
12168
12219
  const turn: BufferTurn = {
12169
12220
  role,
12170
- content,
12221
+ content: bufferedContent,
12171
12222
  timestamp: captureTimestamp,
12172
12223
  // #1578: anchor live-capture turns to wall-clock when bi-temporal is on;
12173
12224
  // replay/import turns carry sourceValidAt explicitly (codex P1).
@@ -13423,23 +13474,16 @@ export class Orchestrator {
13423
13474
  }
13424
13475
 
13425
13476
  // Batch-append persisted IDs so non-fact memories (entities/questions) are
13426
- // always attached to the thread.
13477
+ // always attached to the thread. The helper excludes pending_review ids (#1635).
13427
13478
  if (
13428
13479
  this.config.threadingEnabled &&
13429
13480
  threadIdForExtraction &&
13430
13481
  persistedIds.length > 0
13431
13482
  ) {
13432
- try {
13433
- await this.threading.appendEpisodeIds(
13434
- threadIdForExtraction,
13435
- persistedIds,
13436
- );
13437
- } catch (err) {
13438
- log.warn(
13439
- "[threading] appendEpisodeIds failed after persistence (non-fatal)",
13440
- err,
13441
- );
13442
- }
13483
+ await this.appendPersistedThreadEpisodes(
13484
+ threadIdForExtraction,
13485
+ persistedIds,
13486
+ );
13443
13487
  }
13444
13488
 
13445
13489
  // Thread title update for the already-established thread context.
@@ -13793,9 +13837,11 @@ export class Orchestrator {
13793
13837
  // to avoid a maintenance hazard where the two guard paths could diverge.
13794
13838
  return attachCitation(content, citationContext, citationTemplate);
13795
13839
  };
13840
+ const persistedIds: string[] = [];
13796
13841
  const supersessionOrderingAt = (validAt?: string): string =>
13797
13842
  validAt && validAt.length > 0 ? validAt : new Date().toISOString();
13798
- const persistedIds: string[] = [];
13843
+ // #1635: pending_review persisted ids, excluded from the thread episode set below.
13844
+ const pendingReviewPersistedIds: string[] = [];
13799
13845
  const persistedIdsByStorage = new Map<
13800
13846
  string,
13801
13847
  { storage: StorageManager; ids: string[] }
@@ -13803,11 +13849,18 @@ export class Orchestrator {
13803
13849
  const trackPersistedId = (
13804
13850
  targetStorage: StorageManager,
13805
13851
  id: string,
13806
- options: { includeReturnedIds?: boolean } = {},
13852
+ options: {
13853
+ includeReturnedIds?: boolean;
13854
+ /** #1635: keep this id out of the persisted thread episode set. */
13855
+ pendingReview?: boolean;
13856
+ } = {},
13807
13857
  ): void => {
13808
13858
  if (options.includeReturnedIds !== false) {
13809
13859
  persistedIds.push(id);
13810
13860
  }
13861
+ if (options.pendingReview) {
13862
+ pendingReviewPersistedIds.push(id);
13863
+ }
13811
13864
  const key = targetStorage.dir;
13812
13865
  const existing = persistedIdsByStorage.get(key);
13813
13866
  if (existing) {
@@ -15309,7 +15362,9 @@ export class Orchestrator {
15309
15362
  log.debug(
15310
15363
  `chunked memory ${parentId} into ${chunkResult.chunks.length} chunks`,
15311
15364
  );
15312
- trackPersistedId(targetStorage, parentId);
15365
+ trackPersistedId(targetStorage, parentId, {
15366
+ pendingReview: faithfulnessEnforceStatus === "pending_review",
15367
+ });
15313
15368
  // #1576 (cursor Medium): keep pending_review ids out of threadEpisodeIdsForGraph — else later active facts build thread-predecessor edges to an unfaithful memory.
15314
15369
  if (
15315
15370
  faithfulnessEnforceStatus !== "pending_review" &&
@@ -15595,8 +15650,9 @@ export class Orchestrator {
15595
15650
  source: "extraction",
15596
15651
  }),
15597
15652
  );
15598
- trackPersistedId(targetStorage, memoryId);
15599
- // #1576 (cursor Medium): same thread-episode guard on the non-chunked path.
15653
+ trackPersistedId(targetStorage, memoryId, {
15654
+ pendingReview: faithfulnessEnforceStatus === "pending_review",
15655
+ });
15600
15656
  if (
15601
15657
  faithfulnessEnforceStatus !== "pending_review" &&
15602
15658
  threadEpisodeIdsForGraph &&
@@ -15906,9 +15962,35 @@ export class Orchestrator {
15906
15962
  log.debug(`temporal-index update error (non-fatal): ${err}`),
15907
15963
  );
15908
15964
 
15965
+ // #1635: surface pending_review ids so the thread episode set excludes them.
15966
+ this.lastPersistExtractionPendingReviewIds = pendingReviewPersistedIds;
15909
15967
  // Return the persisted fact IDs for threading
15910
15968
  return persistedIds;
15911
15969
  }
15970
+ /**
15971
+ * Append persisted ids to the thread episode set, excluding pending_review
15972
+ * fact ids (#1635) so they don't re-seed predecessor edges. Fail-open like
15973
+ * the raw appendEpisodeIds call it replaces.
15974
+ */
15975
+ private async appendPersistedThreadEpisodes(
15976
+ threadId: string,
15977
+ persistedIds: string[],
15978
+ ): Promise<void> {
15979
+ const pendingReviewIds = this.lastPersistExtractionPendingReviewIds ?? [];
15980
+ const episodeIds =
15981
+ pendingReviewIds.length > 0
15982
+ ? persistedIds.filter((id) => !pendingReviewIds.includes(id))
15983
+ : persistedIds;
15984
+ if (episodeIds.length === 0) return;
15985
+ try {
15986
+ await this.threading.appendEpisodeIds(threadId, episodeIds);
15987
+ } catch (err) {
15988
+ log.warn(
15989
+ "[threading] appendEpisodeIds failed after persistence (non-fatal)",
15990
+ err,
15991
+ );
15992
+ }
15993
+ }
15912
15994
 
15913
15995
  private async indexPersistedMemory(
15914
15996
  storage: StorageManager,
@@ -17455,13 +17537,28 @@ export class Orchestrator {
17455
17537
  }
17456
17538
  }
17457
17539
 
17458
- private formatQmdResults(title: string, results: QmdSearchResult[]): string {
17540
+ private formatQmdResults(
17541
+ title: string,
17542
+ results: QmdSearchResult[],
17543
+ sessionKey?: string,
17544
+ ): string {
17545
+ // Issue #1582 — handles are only rendered when a session key is available:
17546
+ // resolution requires the handle history to have been recorded for this
17547
+ // session, which only happens when sessionKey is present. Rendering handles
17548
+ // without recording would show tokens a user can never resolve (cursor
17549
+ // review). The rendering logic itself lives in the pure handles module.
17550
+ const handleByIndex = buildHandleIndexForResults(
17551
+ results,
17552
+ this.config.recallMemoryHandles === true && sessionKey != null,
17553
+ );
17459
17554
  const lines = results.map((r, i) => {
17460
17555
  const snippet = r.snippet
17461
17556
  ? r.snippet.slice(0, 500).replace(/\n/g, " ")
17462
17557
  : "(no preview)";
17463
17558
  const source = typeof r.line === "number" ? `${r.path}:${r.line}` : r.path;
17464
- return `[${i + 1}] ${source} (score: ${r.score.toFixed(3)})\n${snippet}`;
17559
+ const head = `[${i + 1}] ${source} (score: ${r.score.toFixed(3)})\n${snippet}`;
17560
+ const handle = handleByIndex.get(i);
17561
+ return handle ? `${head.replace(/\s+$/, "")} ${handle}` : head;
17465
17562
  });
17466
17563
  return `## ${title}\n\n${lines.join("\n\n")}`;
17467
17564
  }
@@ -17826,7 +17923,7 @@ export class Orchestrator {
17826
17923
  this.appendRecallSection(
17827
17924
  options.sectionBuckets,
17828
17925
  sectionId,
17829
- this.formatQmdResults(options.title, options.results),
17926
+ this.formatQmdResults(options.title, options.results, options.sessionKey),
17830
17927
  );
17831
17928
  }
17832
17929
 
@@ -19661,6 +19758,54 @@ export class Orchestrator {
19661
19758
  return this.lastRecall.get(sessionKey);
19662
19759
  }
19663
19760
 
19761
+ /**
19762
+ * Issue #1582 — resolve a memory handle (`[m:4f2a]` / bare hex) to its memory
19763
+ * id against THIS session's recent recall history. Returns the id on a unique
19764
+ * hit, `null` on a miss, and throws on ambiguity (callers must disambiguate —
19765
+ * rule 34/51). Resolution is per-session and snapshot-scoped; there is no
19766
+ * global handle→id map (rule 42).
19767
+ */
19768
+ resolveMemoryHandle(handle: string, sessionKey: string): string | null {
19769
+ if (!sessionKey) return null;
19770
+ const depth = this.config.recallHandleSnapshotDepth;
19771
+ const snapshots: RecallSnapshotIds[] = this.handleHistory
19772
+ .recent(sessionKey, depth)
19773
+ .map((ids) => ({ memoryIds: ids }));
19774
+ const result = resolveHandle(handle, snapshots, depth);
19775
+ if (result.ok) return result.memoryId;
19776
+ if (result.reason === "ambiguous") {
19777
+ throw new Error(
19778
+ `Memory handle ${handle} is ambiguous in session ${sessionKey}: ` +
19779
+ `${result.candidates.join(", ")}. Cite a unique memory id instead.`,
19780
+ );
19781
+ }
19782
+ return null;
19783
+ }
19784
+
19785
+ /**
19786
+ * Issue #1582 — resolve a caller reference that may be EITHER a memory id or
19787
+ * a handle to a concrete memory id. Handles resolve against the session's
19788
+ * recall history; raw ids pass through unchanged. The single shared helper
19789
+ * every surface (memory_get / feedback / outcome / correction targetIds)
19790
+ * calls so handle resolution has one path (rule 22).
19791
+ */
19792
+ resolveMemoryIdOrHandle(ref: string, sessionKey?: string): string {
19793
+ const parsed = parseIdOrHandle(ref);
19794
+ if (!parsed.isHandle) return parsed.value;
19795
+ if (!sessionKey) {
19796
+ throw new Error(
19797
+ `Memory handle ${ref} cannot be resolved without a session key.`,
19798
+ );
19799
+ }
19800
+ const resolved = this.resolveMemoryHandle(parsed.value, sessionKey);
19801
+ if (resolved === null) {
19802
+ throw new Error(
19803
+ `Memory handle ${ref} was not found in the recent recall history for session ${sessionKey}.`,
19804
+ );
19805
+ }
19806
+ return resolved;
19807
+ }
19808
+
19664
19809
  /**
19665
19810
  * Check if a new memory contradicts an existing one.
19666
19811
  * Uses QMD to find similar memories, then LLM to verify contradiction.