@remnic/core 1.1.0 → 1.1.2

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 (308) hide show
  1. package/dist/access-audit.d.ts +56 -0
  2. package/dist/access-audit.js +9 -0
  3. package/dist/access-cli.js +70 -53
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +16 -9
  6. package/dist/access-http.js +26 -18
  7. package/dist/access-mcp.d.ts +16 -9
  8. package/dist/access-mcp.js +30 -8
  9. package/dist/access-schema.d.ts +124 -33
  10. package/dist/access-schema.js +5 -1
  11. package/dist/{access-service-HmO1Trrx.d.ts → access-service-Br8ZydTK.d.ts} +158 -63
  12. package/dist/access-service.d.ts +13 -6
  13. package/dist/access-service.js +23 -14
  14. package/dist/bootstrap.d.ts +6 -3
  15. package/dist/briefing.d.ts +1 -0
  16. package/dist/briefing.js +8 -6
  17. package/dist/buffer-surprise-report.d.ts +70 -0
  18. package/dist/buffer-surprise-report.js +7 -0
  19. package/dist/buffer-surprise-report.js.map +1 -0
  20. package/dist/buffer-surprise.d.ts +98 -0
  21. package/dist/buffer-surprise.js +11 -0
  22. package/dist/buffer-surprise.js.map +1 -0
  23. package/dist/buffer.d.ts +100 -2
  24. package/dist/buffer.js +1 -1
  25. package/dist/calibration.js +6 -6
  26. package/dist/causal-behavior.js +4 -4
  27. package/dist/causal-chain.js +2 -2
  28. package/dist/causal-consolidation.js +19 -18
  29. package/dist/causal-consolidation.js.map +1 -1
  30. package/dist/causal-retrieval.js +4 -4
  31. package/dist/causal-trajectory.js +1 -1
  32. package/dist/{chunk-QNJMBKFK.js → chunk-2LGMW3DJ.js} +3 -2
  33. package/dist/chunk-2LGMW3DJ.js.map +1 -0
  34. package/dist/{chunk-QDYXG4CS.js → chunk-3FPTCC3Z.js} +4 -3
  35. package/dist/chunk-3FPTCC3Z.js.map +1 -0
  36. package/dist/chunk-3GPTTA4J.js +57 -0
  37. package/dist/chunk-3GPTTA4J.js.map +1 -0
  38. package/dist/{chunk-ITRLGI2T.js → chunk-3OGMS3PE.js} +2 -2
  39. package/dist/{chunk-DEPL3635.js → chunk-3YGHKTBF.js} +1446 -196
  40. package/dist/chunk-3YGHKTBF.js.map +1 -0
  41. package/dist/{chunk-BLKTA7MM.js → chunk-4HQS2HPX.js} +54 -21
  42. package/dist/chunk-4HQS2HPX.js.map +1 -0
  43. package/dist/chunk-54V4BZWP.js +139 -0
  44. package/dist/chunk-54V4BZWP.js.map +1 -0
  45. package/dist/chunk-5JRF2PZA.js +67 -0
  46. package/dist/chunk-5JRF2PZA.js.map +1 -0
  47. package/dist/chunk-64NJRYU2.js +332 -0
  48. package/dist/chunk-64NJRYU2.js.map +1 -0
  49. package/dist/{chunk-OIT5QGG4.js → chunk-6AUUAZEX.js} +72 -2
  50. package/dist/chunk-6AUUAZEX.js.map +1 -0
  51. package/dist/{chunk-3QHL5ABG.js → chunk-6YJHX2DL.js} +191 -10
  52. package/dist/chunk-6YJHX2DL.js.map +1 -0
  53. package/dist/chunk-AJU4PJGY.js +126 -0
  54. package/dist/chunk-AJU4PJGY.js.map +1 -0
  55. package/dist/chunk-ASAITVLA.js +64 -0
  56. package/dist/chunk-ASAITVLA.js.map +1 -0
  57. package/dist/{chunk-44ICJRF3.js → chunk-AYXIPSZO.js} +5 -5
  58. package/dist/{chunk-MBJHSA7F.js → chunk-BECYBZLX.js} +265 -20
  59. package/dist/chunk-BECYBZLX.js.map +1 -0
  60. package/dist/chunk-C4SQJZAF.js +486 -0
  61. package/dist/chunk-C4SQJZAF.js.map +1 -0
  62. package/dist/{chunk-6UJ47TVX.js → chunk-CUPFXL3J.js} +2 -2
  63. package/dist/chunk-DF3RVK3X.js +119 -0
  64. package/dist/chunk-DF3RVK3X.js.map +1 -0
  65. package/dist/{chunk-N42IWANG.js → chunk-DG6YMRDC.js} +3 -3
  66. package/dist/chunk-DGVM5SFL.js +69 -0
  67. package/dist/chunk-DGVM5SFL.js.map +1 -0
  68. package/dist/{chunk-3SV6CQHO.js → chunk-DIXB44VE.js} +102 -66
  69. package/dist/chunk-DIXB44VE.js.map +1 -0
  70. package/dist/chunk-EIR5VLIH.js +90 -0
  71. package/dist/chunk-EIR5VLIH.js.map +1 -0
  72. package/dist/{chunk-GV6NLQ4X.js → chunk-F5VP6YCB.js} +374 -16
  73. package/dist/chunk-F5VP6YCB.js.map +1 -0
  74. package/dist/{chunk-6ZH4TU6I.js → chunk-FAAFWE4G.js} +2 -1
  75. package/dist/chunk-FAAFWE4G.js.map +1 -0
  76. package/dist/{chunk-7WQ6SLIE.js → chunk-FVA6TGI3.js} +2 -2
  77. package/dist/{chunk-PAORGQRI.js → chunk-GA5P7RST.js} +37 -23
  78. package/dist/chunk-GA5P7RST.js.map +1 -0
  79. package/dist/chunk-GDFS42HT.js +206 -0
  80. package/dist/chunk-GDFS42HT.js.map +1 -0
  81. package/dist/chunk-IISBCCWR.js +52 -0
  82. package/dist/chunk-IISBCCWR.js.map +1 -0
  83. package/dist/chunk-JBMSGZEQ.js +441 -0
  84. package/dist/chunk-JBMSGZEQ.js.map +1 -0
  85. package/dist/{chunk-J4IYOZZ5.js → chunk-JXS5PDQ7.js} +3 -1
  86. package/dist/chunk-JXS5PDQ7.js.map +1 -0
  87. package/dist/chunk-KVBLZUKV.js +173 -0
  88. package/dist/chunk-KVBLZUKV.js.map +1 -0
  89. package/dist/{chunk-4LACOVZX.js → chunk-L7IXWRYE.js} +10 -5
  90. package/dist/chunk-L7IXWRYE.js.map +1 -0
  91. package/dist/chunk-LBLXEFWK.js +51 -0
  92. package/dist/chunk-LBLXEFWK.js.map +1 -0
  93. package/dist/{chunk-WBSAYXVI.js → chunk-LOIMBRDE.js} +201 -45
  94. package/dist/chunk-LOIMBRDE.js.map +1 -0
  95. package/dist/{chunk-3WHVNEN7.js → chunk-LTCGGW2D.js} +1 -1
  96. package/dist/chunk-LTCGGW2D.js.map +1 -0
  97. package/dist/{chunk-ZVBB3T7V.js → chunk-NBVAS5MT.js} +25 -23
  98. package/dist/chunk-NBVAS5MT.js.map +1 -0
  99. package/dist/{chunk-UEYA6UC7.js → chunk-NZLQTHS5.js} +25 -2
  100. package/dist/chunk-NZLQTHS5.js.map +1 -0
  101. package/dist/{chunk-NQEVYWX6.js → chunk-OC5OXUQ4.js} +211 -7
  102. package/dist/chunk-OC5OXUQ4.js.map +1 -0
  103. package/dist/{chunk-LK6SGL53.js → chunk-OR64ZGRZ.js} +3 -2
  104. package/dist/chunk-OR64ZGRZ.js.map +1 -0
  105. package/dist/{chunk-SYUK3VLY.js → chunk-PVICZTKG.js} +117 -5
  106. package/dist/chunk-PVICZTKG.js.map +1 -0
  107. package/dist/chunk-PVPWZSSI.js +37 -0
  108. package/dist/chunk-PVPWZSSI.js.map +1 -0
  109. package/dist/{chunk-JL2PU6AI.js → chunk-R2XRID2N.js} +2 -2
  110. package/dist/{chunk-4NRAJUDS.js → chunk-RBBWYEFJ.js} +1 -1
  111. package/dist/chunk-RFYAYKTD.js +146 -0
  112. package/dist/chunk-RFYAYKTD.js.map +1 -0
  113. package/dist/chunk-SOBJ6NEY.js +18 -0
  114. package/dist/chunk-SOBJ6NEY.js.map +1 -0
  115. package/dist/{chunk-JIU55F3X.js → chunk-SPI27QT6.js} +2 -2
  116. package/dist/{chunk-MVTHXUBX.js → chunk-STGWEHYR.js} +479 -20
  117. package/dist/chunk-STGWEHYR.js.map +1 -0
  118. package/dist/{chunk-6LX5ORAS.js → chunk-TMYO7B5P.js} +4 -4
  119. package/dist/chunk-TVVEYCNW.js +65 -0
  120. package/dist/chunk-TVVEYCNW.js.map +1 -0
  121. package/dist/chunk-ULYOGL6R.js +322 -0
  122. package/dist/chunk-ULYOGL6R.js.map +1 -0
  123. package/dist/{chunk-37UIFYWO.js → chunk-UWB5LMWY.js} +108 -9
  124. package/dist/chunk-UWB5LMWY.js.map +1 -0
  125. package/dist/{chunk-47UU5PU2.js → chunk-VBVG2M5G.js} +18 -3
  126. package/dist/chunk-VBVG2M5G.js.map +1 -0
  127. package/dist/{chunk-7ECD5ATE.js → chunk-VDX363PS.js} +2 -2
  128. package/dist/{chunk-O5ETUNBT.js → chunk-VTU2B4VF.js} +7 -3
  129. package/dist/chunk-VTU2B4VF.js.map +1 -0
  130. package/dist/{chunk-MTLYEMJB.js → chunk-WCLICCGB.js} +18 -3
  131. package/dist/chunk-WCLICCGB.js.map +1 -0
  132. package/dist/chunk-X6GF3FX2.js +26 -0
  133. package/dist/chunk-X6GF3FX2.js.map +1 -0
  134. package/dist/{chunk-3QFQGRHO.js → chunk-XMHBH5H6.js} +4 -4
  135. package/dist/{chunk-DHHP2Z4X.js → chunk-XXVWLXSG.js} +2 -2
  136. package/dist/{chunk-XZ2TIKGC.js → chunk-Y7R2XJ5Q.js} +25 -9
  137. package/dist/chunk-Y7R2XJ5Q.js.map +1 -0
  138. package/dist/{chunk-ALXMCZEU.js → chunk-Z2E7VW55.js} +6 -3
  139. package/dist/chunk-Z2E7VW55.js.map +1 -0
  140. package/dist/chunk-ZAIM4TUE.js +488 -0
  141. package/dist/chunk-ZAIM4TUE.js.map +1 -0
  142. package/dist/chunk-ZZTOURJI.js +91 -0
  143. package/dist/chunk-ZZTOURJI.js.map +1 -0
  144. package/dist/{cli-BneVIEvh.d.ts → cli-BkeRaYfk.d.ts} +2 -2
  145. package/dist/cli.d.ts +13 -6
  146. package/dist/cli.js +42 -31
  147. package/dist/config.js +2 -2
  148. package/dist/consolidation-operator.d.ts +41 -0
  149. package/dist/consolidation-operator.js +11 -0
  150. package/dist/consolidation-operator.js.map +1 -0
  151. package/dist/consolidation-provenance-check.d.ts +68 -0
  152. package/dist/consolidation-provenance-check.js +9 -0
  153. package/dist/consolidation-provenance-check.js.map +1 -0
  154. package/dist/consolidation-undo.d.ts +123 -0
  155. package/dist/consolidation-undo.js +426 -0
  156. package/dist/consolidation-undo.js.map +1 -0
  157. package/dist/{contradiction-scan-GR33PONM.js → contradiction-scan-E3GJTI4F.js} +43 -7
  158. package/dist/contradiction-scan-E3GJTI4F.js.map +1 -0
  159. package/dist/cross-namespace-budget.d.ts +133 -0
  160. package/dist/cross-namespace-budget.js +9 -0
  161. package/dist/cross-namespace-budget.js.map +1 -0
  162. package/dist/direct-answer-wiring.js +5 -70
  163. package/dist/direct-answer-wiring.js.map +1 -1
  164. package/dist/embedding-fallback.js +2 -1
  165. package/dist/{engine-5TIQBYZR.js → engine-72LSIWQP.js} +8 -7
  166. package/dist/engine-72LSIWQP.js.map +1 -0
  167. package/dist/entity-retrieval.d.ts +1 -0
  168. package/dist/entity-retrieval.js +7 -6
  169. package/dist/explicit-capture.d.ts +6 -3
  170. package/dist/explicit-capture.js +2 -2
  171. package/dist/extraction-judge-telemetry.d.ts +113 -0
  172. package/dist/extraction-judge-telemetry.js +14 -0
  173. package/dist/extraction-judge-telemetry.js.map +1 -0
  174. package/dist/extraction-judge-training.d.ts +85 -0
  175. package/dist/extraction-judge-training.js +16 -0
  176. package/dist/extraction-judge-training.js.map +1 -0
  177. package/dist/extraction-judge.d.ts +124 -2
  178. package/dist/extraction-judge.js +11 -1
  179. package/dist/extraction.js +10 -9
  180. package/dist/fallback-llm.js +3 -3
  181. package/dist/graph-recall.d.ts +100 -0
  182. package/dist/graph-recall.js +8 -0
  183. package/dist/graph-recall.js.map +1 -0
  184. package/dist/graph-retrieval.d.ts +271 -0
  185. package/dist/graph-retrieval.js +21 -0
  186. package/dist/graph-retrieval.js.map +1 -0
  187. package/dist/importance.js +1 -1
  188. package/dist/index.d.ts +585 -20
  189. package/dist/index.js +542 -344
  190. package/dist/index.js.map +1 -1
  191. package/dist/local-llm.js +2 -2
  192. package/dist/memory-worth-bench.d.ts +51 -0
  193. package/dist/memory-worth-bench.js +131 -0
  194. package/dist/memory-worth-bench.js.map +1 -0
  195. package/dist/memory-worth-filter.d.ts +128 -0
  196. package/dist/memory-worth-filter.js +10 -0
  197. package/dist/memory-worth-filter.js.map +1 -0
  198. package/dist/memory-worth-outcomes.d.ts +118 -0
  199. package/dist/memory-worth-outcomes.js +9 -0
  200. package/dist/memory-worth-outcomes.js.map +1 -0
  201. package/dist/memory-worth.d.ts +102 -0
  202. package/dist/memory-worth.js +7 -0
  203. package/dist/memory-worth.js.map +1 -0
  204. package/dist/operator-toolkit.d.ts +40 -1
  205. package/dist/operator-toolkit.js +25 -16
  206. package/dist/{orchestrator-DRYA6_lW.d.ts → orchestrator-CmJ-NTdJ.d.ts} +233 -8
  207. package/dist/orchestrator.d.ts +6 -3
  208. package/dist/orchestrator.js +54 -44
  209. package/dist/page-versioning.d.ts +12 -1
  210. package/dist/page-versioning.js +5 -3
  211. package/dist/{port-C1GZFv8h.d.ts → port-BADbLZU5.d.ts} +2 -2
  212. package/dist/qmd-recall-cache.d.ts +1 -1
  213. package/dist/qmd.d.ts +5 -3
  214. package/dist/qmd.js +3 -3
  215. package/dist/reasoning-trace-recall.d.ts +90 -0
  216. package/dist/reasoning-trace-recall.js +13 -0
  217. package/dist/reasoning-trace-recall.js.map +1 -0
  218. package/dist/reasoning-trace-types.d.ts +54 -0
  219. package/dist/reasoning-trace-types.js +17 -0
  220. package/dist/reasoning-trace-types.js.map +1 -0
  221. package/dist/recall-audit-anomaly.d.ts +112 -0
  222. package/dist/recall-audit-anomaly.js +11 -0
  223. package/dist/recall-audit-anomaly.js.map +1 -0
  224. package/dist/recall-audit.js +5 -44
  225. package/dist/recall-audit.js.map +1 -1
  226. package/dist/recall-explain-renderer.d.ts +49 -0
  227. package/dist/recall-explain-renderer.js +18 -0
  228. package/dist/recall-explain-renderer.js.map +1 -0
  229. package/dist/recall-state.d.ts +12 -1
  230. package/dist/recall-state.js +1 -1
  231. package/dist/recall-xray-cli.d.ts +40 -0
  232. package/dist/recall-xray-cli.js +11 -0
  233. package/dist/recall-xray-cli.js.map +1 -0
  234. package/dist/recall-xray-renderer.d.ts +44 -0
  235. package/dist/recall-xray-renderer.js +18 -0
  236. package/dist/recall-xray-renderer.js.map +1 -0
  237. package/dist/recall-xray.d.ts +179 -0
  238. package/dist/recall-xray.js +13 -0
  239. package/dist/recall-xray.js.map +1 -0
  240. package/dist/resolve-provider-secret.d.ts +5 -1
  241. package/dist/resolve-provider-secret.js +3 -1
  242. package/dist/resume-bundles.js +6 -6
  243. package/dist/retrieval-agents.d.ts +1 -1
  244. package/dist/retrieval-tiers.d.ts +17 -0
  245. package/dist/retrieval-tiers.js +9 -0
  246. package/dist/retrieval-tiers.js.map +1 -0
  247. package/dist/schemas.d.ts +309 -53
  248. package/dist/schemas.js +1 -1
  249. package/dist/{semantic-consolidation-DrvSYRdB.d.ts → semantic-consolidation-CxJU6MJk.d.ts} +62 -1
  250. package/dist/semantic-consolidation.d.ts +2 -1
  251. package/dist/semantic-consolidation.js +22 -7
  252. package/dist/semantic-rule-promotion.js +7 -6
  253. package/dist/semantic-rule-verifier.js +7 -6
  254. package/dist/storage.d.ts +82 -1
  255. package/dist/storage.js +6 -5
  256. package/dist/summarizer.js +6 -6
  257. package/dist/temporal-supersession.d.ts +1 -0
  258. package/dist/tier-migration.d.ts +2 -1
  259. package/dist/tokens.js +2 -1
  260. package/dist/types.d.ts +276 -2
  261. package/dist/types.js +1 -1
  262. package/dist/verified-recall.js +7 -6
  263. package/package.json +1 -1
  264. package/dist/chunk-37UIFYWO.js.map +0 -1
  265. package/dist/chunk-3QHL5ABG.js.map +0 -1
  266. package/dist/chunk-3SV6CQHO.js.map +0 -1
  267. package/dist/chunk-3WHVNEN7.js.map +0 -1
  268. package/dist/chunk-47UU5PU2.js.map +0 -1
  269. package/dist/chunk-4LACOVZX.js.map +0 -1
  270. package/dist/chunk-6ZH4TU6I.js.map +0 -1
  271. package/dist/chunk-ALXMCZEU.js.map +0 -1
  272. package/dist/chunk-BLKTA7MM.js.map +0 -1
  273. package/dist/chunk-DEPL3635.js.map +0 -1
  274. package/dist/chunk-GV6NLQ4X.js.map +0 -1
  275. package/dist/chunk-J4IYOZZ5.js.map +0 -1
  276. package/dist/chunk-LAYN4LDC.js +0 -267
  277. package/dist/chunk-LAYN4LDC.js.map +0 -1
  278. package/dist/chunk-LK6SGL53.js.map +0 -1
  279. package/dist/chunk-MBJHSA7F.js.map +0 -1
  280. package/dist/chunk-MTLYEMJB.js.map +0 -1
  281. package/dist/chunk-MVTHXUBX.js.map +0 -1
  282. package/dist/chunk-NQEVYWX6.js.map +0 -1
  283. package/dist/chunk-O5ETUNBT.js.map +0 -1
  284. package/dist/chunk-OIT5QGG4.js.map +0 -1
  285. package/dist/chunk-PAORGQRI.js.map +0 -1
  286. package/dist/chunk-QDYXG4CS.js.map +0 -1
  287. package/dist/chunk-QNJMBKFK.js.map +0 -1
  288. package/dist/chunk-SYUK3VLY.js.map +0 -1
  289. package/dist/chunk-UEYA6UC7.js.map +0 -1
  290. package/dist/chunk-UVJFDP7P.js +0 -202
  291. package/dist/chunk-UVJFDP7P.js.map +0 -1
  292. package/dist/chunk-WBSAYXVI.js.map +0 -1
  293. package/dist/chunk-XZ2TIKGC.js.map +0 -1
  294. package/dist/chunk-ZVBB3T7V.js.map +0 -1
  295. package/dist/contradiction-scan-GR33PONM.js.map +0 -1
  296. /package/dist/{engine-5TIQBYZR.js.map → access-audit.js.map} +0 -0
  297. /package/dist/{chunk-ITRLGI2T.js.map → chunk-3OGMS3PE.js.map} +0 -0
  298. /package/dist/{chunk-44ICJRF3.js.map → chunk-AYXIPSZO.js.map} +0 -0
  299. /package/dist/{chunk-6UJ47TVX.js.map → chunk-CUPFXL3J.js.map} +0 -0
  300. /package/dist/{chunk-N42IWANG.js.map → chunk-DG6YMRDC.js.map} +0 -0
  301. /package/dist/{chunk-7WQ6SLIE.js.map → chunk-FVA6TGI3.js.map} +0 -0
  302. /package/dist/{chunk-JL2PU6AI.js.map → chunk-R2XRID2N.js.map} +0 -0
  303. /package/dist/{chunk-4NRAJUDS.js.map → chunk-RBBWYEFJ.js.map} +0 -0
  304. /package/dist/{chunk-JIU55F3X.js.map → chunk-SPI27QT6.js.map} +0 -0
  305. /package/dist/{chunk-6LX5ORAS.js.map → chunk-TMYO7B5P.js.map} +0 -0
  306. /package/dist/{chunk-7ECD5ATE.js.map → chunk-VDX363PS.js.map} +0 -0
  307. /package/dist/{chunk-3QFQGRHO.js.map → chunk-XMHBH5H6.js.map} +0 -0
  308. /package/dist/{chunk-DHHP2Z4X.js.map → chunk-XXVWLXSG.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/access-mcp.ts"],"sourcesContent":["import type { Readable, Writable } from \"node:stream\";\nimport { readFile } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport type { EngramAccessService, EngramAccessRecallResponse } from \"./access-service.js\";\nimport { readEnvVar } from \"./runtime/env.js\";\nimport type { RecallPlanMode } from \"./types.js\";\nimport { validateBriefingFormat } from \"./briefing.js\";\nimport { buildCitationGuidance, type CitationMetadata } from \"./citations.js\";\n\ntype JsonRpcId = string | number | null;\n\ntype JsonRpcRequest = {\n jsonrpc?: string;\n id?: JsonRpcId;\n method?: string;\n params?: Record<string, unknown>;\n};\n\ntype McpTool = {\n name: string;\n description: string;\n inputSchema: Record<string, unknown>;\n};\n\nconst MCP_PROTOCOL_VERSION = \"2024-11-05\";\nconst LEGACY_MCP_PREFIX = \"engram.\";\nconst CANONICAL_MCP_PREFIX = \"remnic.\";\n\nfunction toCanonicalToolName(name: string): string {\n return name.startsWith(LEGACY_MCP_PREFIX)\n ? `${CANONICAL_MCP_PREFIX}${name.slice(LEGACY_MCP_PREFIX.length)}`\n : name;\n}\n\nfunction toLegacyToolName(name: string): string {\n return name.startsWith(CANONICAL_MCP_PREFIX)\n ? `${LEGACY_MCP_PREFIX}${name.slice(CANONICAL_MCP_PREFIX.length)}`\n : name;\n}\n\nfunction withToolAliases(tool: McpTool): McpTool[] {\n const canonicalName = toCanonicalToolName(tool.name);\n const canonicalTool = canonicalName === tool.name ? tool : { ...tool, name: canonicalName };\n if (canonicalName === tool.name) return [canonicalTool];\n return [canonicalTool, tool];\n}\n\nasync function getMcpServerVersion(): Promise<string> {\n const envVersion =\n readEnvVar(\"OPENCLAW_ENGRAM_VERSION\")?.trim() ||\n readEnvVar(\"npm_package_version\")?.trim();\n if (envVersion) return envVersion;\n try {\n const pkgPath = new URL(\"../package.json\", import.meta.url);\n const raw = await readFile(pkgPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { version?: string };\n return parsed.version?.trim() || \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nexport class EngramMcpServer {\n private buffer = Buffer.alloc(0);\n private flushTask: Promise<void> | null = null;\n private readonly tools: McpTool[];\n private readonly authenticatedPrincipal?: string;\n /**\n * MCP client info keyed by server-assigned session ID. On each `initialize`\n * handshake the server generates a UUID, stores the client's clientInfo\n * against it, and returns the ID as `Mcp-Session-Id` in the response\n * metadata. Subsequent requests from the same client include this header,\n * allowing per-session clientInfo lookup without cross-session leaks.\n */\n private clientInfoBySession = new Map<string, { name: string; version?: string }>();\n /**\n * Session IDs generated during initialize, keyed by caller-supplied correlation\n * ID (unique per HTTP request) to avoid collisions when multiple clients send\n * initialize with the same JSON-RPC id concurrently.\n */\n private initSessionIds = new Map<string, string>();\n\n /** Whether oai-mem-citation guidance is explicitly enabled via config. */\n private readonly citationsEnabled: boolean;\n /** Whether to auto-enable citations for Codex adapter connections. */\n private readonly citationsAutoDetect: boolean;\n\n constructor(\n private readonly service: EngramAccessService,\n options: { principal?: string; citationsEnabled?: boolean; citationsAutoDetect?: boolean } = {},\n ) {\n this.citationsEnabled = options.citationsEnabled === true;\n this.citationsAutoDetect = options.citationsAutoDetect !== false;\n this.authenticatedPrincipal =\n options.principal?.trim() ||\n readEnvVar(\"OPENCLAW_ENGRAM_ACCESS_PRINCIPAL\")?.trim() ||\n undefined;\n this.tools = [\n {\n name: \"engram.recall\",\n description: \"Recall Engram context for a query.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\" },\n sessionKey: { type: \"string\" },\n namespace: { type: \"string\" },\n topK: { type: \"number\" },\n mode: { type: \"string\", enum: [\"auto\", \"no_recall\", \"minimal\", \"full\", \"graph_mode\"] },\n includeDebug: { type: \"boolean\" },\n },\n required: [\"query\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.recall_explain\",\n description: \"Return the last recall snapshot for a session or the most recent one.\",\n inputSchema: {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\" },\n namespace: { type: \"string\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.day_summary\",\n description:\n \"Generate a structured end-of-day summary. When memories is omitted or empty, auto-gathers today's facts and hourly summaries from storage.\",\n inputSchema: {\n type: \"object\",\n properties: {\n memories: { type: \"string\" },\n sessionKey: { type: \"string\" },\n namespace: { type: \"string\" },\n },\n required: [],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_governance_run\",\n description: \"Run Remnic memory governance in a bounded shadow/apply pass.\",\n inputSchema: {\n type: \"object\",\n properties: {\n namespace: { type: \"string\" },\n mode: { type: \"string\", enum: [\"shadow\", \"apply\"] },\n recentDays: { type: \"number\" },\n maxMemories: { type: \"number\" },\n batchSize: { type: \"number\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.procedure_mining_run\",\n description:\n \"Run procedural memory mining from causal trajectories (issue #519). Respects procedural.enabled; writes under procedures/ when clusters qualify.\",\n inputSchema: {\n type: \"object\",\n properties: {\n namespace: { type: \"string\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_get\",\n description: \"Fetch one Remnic memory by id.\",\n inputSchema: {\n type: \"object\",\n properties: {\n memoryId: { type: \"string\" },\n namespace: { type: \"string\" },\n },\n required: [\"memoryId\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_timeline\",\n description: \"Fetch one Remnic memory timeline by id.\",\n inputSchema: {\n type: \"object\",\n properties: {\n memoryId: { type: \"string\" },\n namespace: { type: \"string\" },\n limit: { type: \"number\" },\n },\n required: [\"memoryId\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_store\",\n description: \"Store an explicit Remnic memory through the access layer.\",\n inputSchema: {\n type: \"object\",\n properties: {\n schemaVersion: { type: \"number\" },\n idempotencyKey: { type: \"string\" },\n dryRun: { type: \"boolean\" },\n sessionKey: { type: \"string\" },\n content: { type: \"string\" },\n category: { type: \"string\" },\n confidence: { type: \"number\" },\n namespace: { type: \"string\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n entityRef: { type: \"string\" },\n ttl: { type: \"string\" },\n sourceReason: { type: \"string\" },\n },\n required: [\"content\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.suggestion_submit\",\n description: \"Queue a suggested Remnic memory for review.\",\n inputSchema: {\n type: \"object\",\n properties: {\n schemaVersion: { type: \"number\" },\n idempotencyKey: { type: \"string\" },\n dryRun: { type: \"boolean\" },\n sessionKey: { type: \"string\" },\n content: { type: \"string\" },\n category: { type: \"string\" },\n confidence: { type: \"number\" },\n namespace: { type: \"string\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n entityRef: { type: \"string\" },\n ttl: { type: \"string\" },\n sourceReason: { type: \"string\" },\n },\n required: [\"content\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.entity_get\",\n description: \"Fetch one Engram entity by name.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n namespace: { type: \"string\" },\n },\n required: [\"name\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.review_queue_list\",\n description: \"Fetch the latest Engram review queue artifact bundle.\",\n inputSchema: {\n type: \"object\",\n properties: {\n runId: { type: \"string\" },\n namespace: { type: \"string\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.observe\",\n description: \"Feed conversation messages into Engram's memory pipeline (LCM archive + extraction).\",\n inputSchema: {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\", description: \"Conversation session identifier\" },\n messages: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n role: { type: \"string\", enum: [\"user\", \"assistant\"] },\n content: { type: \"string\" },\n },\n required: [\"role\", \"content\"],\n },\n description: \"Conversation messages to observe\",\n },\n namespace: { type: \"string\" },\n skipExtraction: { type: \"boolean\" },\n },\n required: [\"sessionKey\", \"messages\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.lcm_search\",\n description: \"Search the LCM conversation archive for matching content.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"Search query\" },\n sessionKey: { type: \"string\", description: \"Optional session filter\" },\n namespace: { type: \"string\" },\n limit: { type: \"number\", description: \"Max results to return\" },\n },\n required: [\"query\"],\n additionalProperties: false,\n },\n },\n // ── Continuity / Identity tools ─────────────────────────────────────\n {\n name: \"engram.continuity_audit_generate\",\n description: \"Generate a deterministic identity continuity audit report (weekly/monthly).\",\n inputSchema: {\n type: \"object\",\n properties: {\n period: { type: \"string\", enum: [\"weekly\", \"monthly\"] },\n key: { type: \"string\", description: \"Period key (weekly: YYYY-Www, monthly: YYYY-MM). Defaults to current.\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.continuity_incident_open\",\n description: \"Create a new continuity incident record in append-only storage.\",\n inputSchema: {\n type: \"object\",\n properties: {\n symptom: { type: \"string\", description: \"Observed continuity failure symptom.\" },\n namespace: { type: \"string\" },\n triggerWindow: { type: \"string\", description: \"Time window when incident occurred.\" },\n suspectedCause: { type: \"string\" },\n },\n required: [\"symptom\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.continuity_incident_close\",\n description: \"Close an open continuity incident with verification details.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Incident ID to close.\" },\n namespace: { type: \"string\" },\n fixApplied: { type: \"string\", description: \"What fix was applied.\" },\n verificationResult: { type: \"string\", description: \"How closure was verified.\" },\n preventiveRule: { type: \"string\", description: \"Optional preventive follow-up rule.\" },\n },\n required: [\"id\", \"fixApplied\", \"verificationResult\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.continuity_incident_list\",\n description: \"List continuity incidents, optionally filtered by state.\",\n inputSchema: {\n type: \"object\",\n properties: {\n state: { type: \"string\", enum: [\"open\", \"closed\", \"all\"] },\n namespace: { type: \"string\" },\n limit: { type: \"number\", description: \"Max incidents (default 25, max 200).\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.continuity_loop_add_or_update\",\n description: \"Add or update a continuity improvement loop entry.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Stable loop identifier.\" },\n cadence: { type: \"string\", enum: [\"daily\", \"weekly\", \"monthly\", \"quarterly\"] },\n purpose: { type: \"string\", description: \"What this recurring loop improves.\" },\n status: { type: \"string\", enum: [\"active\", \"paused\", \"retired\"] },\n killCondition: { type: \"string\", description: \"Clear condition for retiring this loop.\" },\n namespace: { type: \"string\" },\n lastReviewed: { type: \"string\", description: \"ISO timestamp for last review.\" },\n notes: { type: \"string\" },\n },\n required: [\"id\", \"cadence\", \"purpose\", \"status\", \"killCondition\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.continuity_loop_review\",\n description: \"Update review metadata for an existing continuity improvement loop.\",\n inputSchema: {\n type: \"object\",\n properties: {\n id: { type: \"string\", description: \"Loop ID to review.\" },\n namespace: { type: \"string\" },\n status: { type: \"string\", enum: [\"active\", \"paused\", \"retired\"] },\n notes: { type: \"string\" },\n reviewedAt: { type: \"string\", description: \"ISO timestamp for review event.\" },\n },\n required: [\"id\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.identity_anchor_get\",\n description: \"Read the identity continuity anchor document (recovery-safe identity context).\",\n inputSchema: {\n type: \"object\",\n properties: {\n namespace: { type: \"string\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.identity_anchor_update\",\n description: \"Conservatively merge identity anchor sections without overwriting existing material.\",\n inputSchema: {\n type: \"object\",\n properties: {\n namespace: { type: \"string\" },\n identityTraits: { type: \"string\", description: \"Updates for 'Identity Traits' section.\" },\n communicationPreferences: { type: \"string\", description: \"Updates for 'Communication Preferences' section.\" },\n operatingPrinciples: { type: \"string\", description: \"Updates for 'Operating Principles' section.\" },\n continuityNotes: { type: \"string\", description: \"Updates for 'Continuity Notes' section.\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_identity\",\n description: \"Read the agent's identity reflections from the workspace IDENTITY.md file.\",\n inputSchema: {\n type: \"object\",\n properties: {\n namespace: { type: \"string\" },\n },\n additionalProperties: false,\n },\n },\n // ── Work Layer tools ─────────────────────────────────────────────────\n {\n name: \"engram.work_task\",\n description: \"Manage work-layer tasks (create, get, list, update, transition, delete). Excluded from memory extraction.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"create\", \"get\", \"list\", \"update\", \"transition\", \"delete\"] },\n id: { type: \"string\" },\n title: { type: \"string\" },\n description: { type: \"string\" },\n status: { type: \"string\", enum: [\"todo\", \"in_progress\", \"blocked\", \"done\", \"cancelled\"] },\n priority: { type: \"string\", enum: [\"low\", \"medium\", \"high\"] },\n owner: { type: \"string\" },\n assignee: { type: \"string\" },\n projectId: { type: \"string\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n dueAt: { type: \"string\" },\n },\n required: [\"action\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.work_project\",\n description: \"Manage work-layer projects (create, get, list, update, delete, link_task). Excluded from memory extraction.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"create\", \"get\", \"list\", \"update\", \"delete\", \"link_task\"] },\n id: { type: \"string\" },\n name: { type: \"string\" },\n description: { type: \"string\" },\n status: { type: \"string\", enum: [\"active\", \"on_hold\", \"completed\", \"archived\"] },\n owner: { type: \"string\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n taskId: { type: \"string\", description: \"Task ID for link_task.\" },\n projectId: { type: \"string\", description: \"Project ID for link_task.\" },\n },\n required: [\"action\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.work_board\",\n description: \"Export/import work-layer board snapshots and markdown.\",\n inputSchema: {\n type: \"object\",\n properties: {\n action: { type: \"string\", enum: [\"export_markdown\", \"export_snapshot\", \"import_snapshot\"] },\n projectId: { type: \"string\" },\n snapshotJson: { type: \"string\", description: \"Snapshot JSON for import_snapshot.\" },\n linkToMemory: { type: \"boolean\", description: \"If true, output can be retained as long-term memory.\" },\n },\n required: [\"action\"],\n additionalProperties: false,\n },\n },\n // ── Shared Context / Compounding tools ────────────────────────────\n {\n name: \"engram.shared_context_write_output\",\n description: \"Write agent work product into shared-context directory for cross-agent coordination.\",\n inputSchema: {\n type: \"object\",\n properties: {\n agentId: { type: \"string\", description: \"Agent ID producing this output.\" },\n title: { type: \"string\", description: \"Short title for the output.\" },\n content: { type: \"string\", description: \"Markdown content to write.\" },\n },\n required: [\"agentId\", \"title\", \"content\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.shared_feedback_record\",\n description: \"Append approval/rejection decision into shared-context feedback inbox for compounding learning.\",\n inputSchema: {\n type: \"object\",\n properties: {\n agent: { type: \"string\", description: \"Agent name that produced the output.\" },\n decision: { type: \"string\", enum: [\"approved\", \"approved_with_feedback\", \"rejected\"] },\n reason: { type: \"string\" },\n date: { type: \"string\", description: \"ISO timestamp. Defaults to now.\" },\n learning: { type: \"string\" },\n outcome: { type: \"string\" },\n severity: { type: \"string\", enum: [\"low\", \"medium\", \"high\"] },\n confidence: { type: \"number\", description: \"Confidence 0-1.\" },\n workflow: { type: \"string\" },\n tags: { type: \"array\", items: { type: \"string\" } },\n evidenceWindowStart: { type: \"string\" },\n evidenceWindowEnd: { type: \"string\" },\n refs: { type: \"array\", items: { type: \"string\" } },\n },\n required: [\"agent\", \"decision\", \"reason\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.shared_priorities_append\",\n description: \"Append priorities text into shared-context inbox for curator merge.\",\n inputSchema: {\n type: \"object\",\n properties: {\n agentId: { type: \"string\" },\n text: { type: \"string\", description: \"Priority notes (markdown).\" },\n },\n required: [\"agentId\", \"text\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.shared_context_cross_signals_run\",\n description: \"Generate cross-signal markdown + JSON artifacts from agent outputs and feedback.\",\n inputSchema: {\n type: \"object\",\n properties: {\n date: { type: \"string\", description: \"YYYY-MM-DD. Defaults to today.\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.shared_context_curate_daily\",\n description: \"Generate daily roundtable summary (deterministic baseline aggregation).\",\n inputSchema: {\n type: \"object\",\n properties: {\n date: { type: \"string\", description: \"YYYY-MM-DD. Defaults to today.\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.compounding_weekly_synthesize\",\n description: \"Generate weekly compounding outputs: reports, mistake registry, rubrics, and promotion candidates.\",\n inputSchema: {\n type: \"object\",\n properties: {\n weekId: { type: \"string\", description: \"ISO week ID (YYYY-Www). Defaults to current week.\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.compounding_promote_candidate\",\n description: \"Promote a compounding candidate from weekly report into durable rule/principle memory.\",\n inputSchema: {\n type: \"object\",\n properties: {\n weekId: { type: \"string\" },\n candidateId: { type: \"string\" },\n dryRun: { type: \"boolean\", description: \"Preview without writing.\" },\n },\n required: [\"weekId\", \"candidateId\"],\n additionalProperties: false,\n },\n },\n // ── Compression Guidelines tools ────────────────────────────────────\n {\n name: \"engram.compression_guidelines_optimize\",\n description: \"Run compression guideline optimizer, optionally persisting new guidelines.\",\n inputSchema: {\n type: \"object\",\n properties: {\n dryRun: { type: \"boolean\" },\n eventLimit: { type: \"number\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.compression_guidelines_activate\",\n description: \"Promote staged compression guideline draft to active (after review).\",\n inputSchema: {\n type: \"object\",\n properties: {\n expectedContentHash: { type: \"string\" },\n expectedGuidelineVersion: { type: \"number\" },\n },\n additionalProperties: false,\n },\n },\n // ── Memory search & debug tools ────────────────────────────────────\n {\n name: \"engram.memory_search\",\n description: \"Direct semantic search over memory files using the QMD index. Returns matching memories with relevance scores.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\" },\n namespace: { type: \"string\" },\n maxResults: { type: \"number\" },\n collection: { type: \"string\", description: \"QMD collection (omit for memory, 'global' for all)\" },\n },\n required: [\"query\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_profile\",\n description: \"Read the user's behavioral profile — a living document of their preferences, habits, and personality.\",\n inputSchema: {\n type: \"object\",\n properties: { namespace: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_entities_list\",\n description: \"List all tracked entities (people, projects, tools, companies).\",\n inputSchema: {\n type: \"object\",\n properties: { namespace: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_questions\",\n description: \"List open questions the system is curious about from past conversations.\",\n inputSchema: {\n type: \"object\",\n properties: { namespace: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_last_recall\",\n description: \"Return the last recall snapshot for a session (debug introspection).\",\n inputSchema: {\n type: \"object\",\n properties: { sessionKey: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_intent_debug\",\n description: \"Return the last intent classification debug snapshot.\",\n inputSchema: {\n type: \"object\",\n properties: { namespace: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_qmd_debug\",\n description: \"Return QMD search index debug information from the last recall.\",\n inputSchema: {\n type: \"object\",\n properties: { namespace: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_graph_explain\",\n description: \"Explain the last entity graph recall — which entities were activated and why.\",\n inputSchema: {\n type: \"object\",\n properties: { namespace: { type: \"string\" } },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_feedback\",\n description: \"Record relevance feedback (thumbs up/down) for a specific memory.\",\n inputSchema: {\n type: \"object\",\n properties: {\n memoryId: { type: \"string\" },\n vote: { type: \"string\", enum: [\"up\", \"down\"] },\n note: { type: \"string\" },\n },\n required: [\"memoryId\", \"vote\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.memory_promote\",\n description: \"Promote a memory's lifecycle state (e.g. from draft to active).\",\n inputSchema: {\n type: \"object\",\n properties: {\n memoryId: { type: \"string\" },\n namespace: { type: \"string\" },\n sessionKey: { type: \"string\" },\n },\n required: [\"memoryId\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.context_checkpoint\",\n description: \"Save a structured context checkpoint for a session (preserves conversation state to disk).\",\n inputSchema: {\n type: \"object\",\n properties: {\n sessionKey: { type: \"string\" },\n context: { type: \"string\", description: \"Context content to checkpoint\" },\n namespace: { type: \"string\" },\n },\n required: [\"sessionKey\", \"context\"],\n additionalProperties: false,\n },\n },\n // ── Daily Context Briefing (#370) ───────────────────────────────────\n // Uses the legacy \"engram.*\" prefix like every other tool in this array;\n // withToolAliases (applied via .flatMap below) generates the canonical\n // \"remnic.briefing\" alias automatically.\n ...(service.briefingEnabled ? [{\n name: \"engram.briefing\",\n description: \"Generate a daily context briefing by cross-referencing active entities, recent facts, open commitments, and optional calendar events.\",\n inputSchema: {\n type: \"object\",\n properties: {\n since: { type: \"string\", description: \"Lookback window (e.g. 'yesterday', '3d', '1w', '24h').\" },\n focus: { type: \"string\", description: \"Optional focus filter (e.g. 'person:Jane Doe', 'project:remnic-core', 'topic:retrieval').\" },\n namespace: { type: \"string\" },\n format: { type: \"string\", enum: [\"markdown\", \"json\"] },\n maxFollowups: { type: \"number\", description: \"Maximum LLM-suggested follow-ups (0 disables that section).\" },\n },\n additionalProperties: false,\n },\n }] : []),\n // ── Contradiction Review (issue #520) ────────────────────────────────\n {\n name: \"engram.review_list\",\n description: \"List contradiction review items pending user resolution.\",\n inputSchema: {\n type: \"object\",\n properties: {\n filter: { type: \"string\", enum: [\"all\", \"unresolved\", \"contradicts\", \"independent\", \"duplicates\", \"needs-user\"], description: \"Filter by verdict type. Default: unresolved.\" },\n namespace: { type: \"string\" },\n limit: { type: \"number\", description: \"Max items to return (default 50).\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"engram.review_resolve\",\n description: \"Resolve a contradiction pair with a chosen verb.\",\n inputSchema: {\n type: \"object\",\n properties: {\n pairId: { type: \"string\", description: \"The contradiction pair ID to resolve.\" },\n verb: { type: \"string\", enum: [\"keep-a\", \"keep-b\", \"merge\", \"both-valid\", \"needs-more-context\"], description: \"Resolution action.\" },\n },\n required: [\"pairId\", \"verb\"],\n additionalProperties: false,\n },\n },\n {\n name: \"engram.contradiction_scan_run\",\n description: \"Run an on-demand contradiction scan over the memory corpus.\",\n inputSchema: {\n type: \"object\",\n properties: {\n namespace: { type: \"string\" },\n },\n additionalProperties: false,\n },\n },\n ].flatMap((tool) => withToolAliases(tool));\n }\n\n /** Get clientInfo for a specific MCP session. Returns undefined for non-MCP requests. */\n getClientInfo(sessionId?: string): { name: string; version?: string } | undefined {\n if (sessionId) {\n return this.clientInfoBySession.get(sessionId);\n }\n return undefined;\n }\n\n /** Pop the session ID generated during an initialize handshake, keyed by correlation ID. */\n popInitSessionId(correlationId: string): string | undefined {\n const sid = this.initSessionIds.get(correlationId);\n if (sid !== undefined) this.initSessionIds.delete(correlationId);\n return sid;\n }\n\n async handleRequest(request: JsonRpcRequest, options?: { principalOverride?: string; sessionId?: string; correlationId?: string }): Promise<Record<string, unknown> | null> {\n const id = request.id ?? null;\n const method = request.method ?? \"\";\n\n if (method === \"notifications/initialized\") return null;\n if (method === \"ping\") {\n return { jsonrpc: \"2.0\", id, result: {} };\n }\n if (method === \"initialize\") {\n const params = request.params ?? {};\n const rawClientInfo = params.clientInfo as { name?: string; version?: string } | undefined;\n // Generate a server-side session ID for this MCP session.\n // The caller should send this back as Mcp-Session-Id on subsequent requests.\n const newSessionId = randomUUID();\n if (rawClientInfo && typeof rawClientInfo.name === \"string\") {\n const info = { name: rawClientInfo.name, version: rawClientInfo.version as string | undefined };\n this.clientInfoBySession.set(newSessionId, info);\n // Evict oldest sessions if map exceeds limit\n if (this.clientInfoBySession.size > 1000) {\n const firstKey = this.clientInfoBySession.keys().next().value;\n if (firstKey) this.clientInfoBySession.delete(firstKey);\n }\n }\n const version = await getMcpServerVersion();\n // Store session ID keyed by correlation ID (unique per HTTP request) so\n // concurrent initializes with the same JSON-RPC id don't collide.\n const corrId = options?.correlationId;\n if (corrId) this.initSessionIds.set(corrId, newSessionId);\n return {\n jsonrpc: \"2.0\",\n id,\n result: {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: {\n tools: {},\n },\n serverInfo: {\n name: \"remnic\",\n version,\n },\n },\n };\n }\n if (method === \"tools/list\") {\n return {\n jsonrpc: \"2.0\",\n id,\n result: {\n tools: this.tools,\n },\n };\n }\n if (method === \"tools/call\") {\n const params = request.params ?? {};\n const name = typeof params.name === \"string\" ? params.name : \"\";\n const argumentsObject =\n params.arguments && typeof params.arguments === \"object\" && !Array.isArray(params.arguments)\n ? (params.arguments as Record<string, unknown>)\n : {};\n\n try {\n const effectivePrincipal = options?.principalOverride ?? this.authenticatedPrincipal;\n const result = await this.callTool(name, argumentsObject, effectivePrincipal, options?.sessionId);\n return {\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: JSON.stringify(result, null, 2) }],\n structuredContent: result,\n isError: false,\n },\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n jsonrpc: \"2.0\",\n id,\n result: {\n content: [{ type: \"text\", text: message }],\n isError: true,\n },\n };\n }\n }\n\n return {\n jsonrpc: \"2.0\",\n id,\n error: {\n code: -32601,\n message: `Method not found: ${method}`,\n },\n };\n }\n\n async runStdio(input: Readable, output: Writable): Promise<void> {\n input.on(\"data\", (chunk) => {\n this.buffer = Buffer.concat([this.buffer, Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)]);\n this.scheduleFlush(output);\n });\n await new Promise<void>((resolve, reject) => {\n input.on(\"end\", resolve);\n input.on(\"error\", reject);\n });\n while (this.flushTask) {\n await this.flushTask;\n }\n }\n\n private scheduleFlush(output: Writable): void {\n if (this.flushTask) return;\n const task = this.flushBuffer(output)\n .catch((err) => {\n this.writeMessage(output, {\n jsonrpc: \"2.0\",\n id: null,\n error: {\n code: -32700,\n message: err instanceof Error ? err.message : String(err),\n },\n });\n })\n .finally(() => {\n if (this.flushTask === task) {\n this.flushTask = null;\n }\n if (this.buffer.length > 0) {\n this.scheduleFlush(output);\n }\n });\n this.flushTask = task;\n }\n\n private async flushBuffer(output: Writable): Promise<void> {\n while (true) {\n const headerEnd = this.buffer.indexOf(\"\\r\\n\\r\\n\");\n if (headerEnd < 0) return;\n const headerText = this.buffer.slice(0, headerEnd).toString(\"utf-8\");\n const headers = headerText.split(\"\\r\\n\");\n const contentLengthHeader = headers.find((line) => line.toLowerCase().startsWith(\"content-length:\"));\n if (!contentLengthHeader) {\n this.buffer = Buffer.alloc(0);\n return;\n }\n const contentLength = parseInt(contentLengthHeader.split(\":\")[1]?.trim() ?? \"0\", 10);\n if (!Number.isFinite(contentLength) || contentLength < 0) {\n this.buffer = Buffer.alloc(0);\n return;\n }\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n if (this.buffer.length < messageEnd) return;\n const body = this.buffer.slice(messageStart, messageEnd).toString(\"utf-8\");\n this.buffer = this.buffer.slice(messageEnd);\n\n let parsed: JsonRpcRequest;\n try {\n parsed = JSON.parse(body) as JsonRpcRequest;\n } catch {\n this.writeMessage(output, {\n jsonrpc: \"2.0\",\n id: null,\n error: {\n code: -32700,\n message: \"Parse error\",\n },\n });\n continue;\n }\n const response = await this.handleRequest(parsed);\n if (response) {\n this.writeMessage(output, response);\n }\n }\n }\n\n private writeMessage(output: Writable, payload: Record<string, unknown>): void {\n const body = JSON.stringify(payload);\n const message = `Content-Length: ${Buffer.byteLength(body, \"utf-8\")}\\r\\n\\r\\n${body}`;\n output.write(message);\n }\n\n /**\n * Determine whether oai-mem-citation guidance should be appended to recall.\n * Returns true when explicitly enabled via config OR when auto-detect is\n * active and the current MCP session belongs to a Codex adapter client.\n *\n * When no sessionId is provided (e.g., stdio transport where there are no\n * HTTP headers carrying mcp-session-id), fall back to checking if there is\n * exactly one known session whose clientInfo matches the Codex pattern.\n * This covers the common stdio case where a single client connection exists.\n */\n private shouldEmitCitations(mcpSessionId?: string): boolean {\n if (this.citationsEnabled) return true;\n if (!this.citationsAutoDetect) return false;\n\n // Direct session lookup (HTTP transport with mcp-session-id header).\n if (mcpSessionId) {\n const info = this.clientInfoBySession.get(mcpSessionId);\n if (!info) return false;\n return this.isCodexClient(info);\n }\n\n // Stdio fallback: no session ID available. If there is exactly one session\n // registered (the typical stdio pattern), check that session's clientInfo.\n if (this.clientInfoBySession.size === 1) {\n const [info] = [...this.clientInfoBySession.values()];\n if (info) return this.isCodexClient(info);\n }\n\n return false;\n }\n\n /** Check whether a clientInfo record identifies a Codex adapter client. */\n private isCodexClient(info: { name: string; version?: string }): boolean {\n const lowerName = info.name.toLowerCase();\n return lowerName === \"codex-mcp-client\" || lowerName.includes(\"codex\");\n }\n\n /**\n * Build citation metadata for each recall result that has a path.\n * Line range defaults to 1-1 when not determinable from the summary.\n */\n private buildRecallCitations(response: EngramAccessRecallResponse): CitationMetadata[] {\n return response.results\n .filter((r) => r.path && r.path.length > 0)\n .map((r) => ({\n memoryId: r.id,\n path: r.path,\n lineStart: 1,\n lineEnd: 1,\n noteDefault: r.preview?.slice(0, 60) || r.id,\n }));\n }\n\n private async callTool(name: string, args: Record<string, unknown>, effectivePrincipal?: string, mcpSessionId?: string): Promise<unknown> {\n switch (toLegacyToolName(name)) {\n case \"engram.recall\": {\n const response = await this.service.recall({\n query: typeof args.query === \"string\" ? args.query : \"\",\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n topK: typeof args.topK === \"number\" && Number.isFinite(args.topK) ? args.topK : undefined,\n mode: typeof args.mode === \"string\" ? args.mode as RecallPlanMode | \"auto\" : undefined,\n includeDebug: args.includeDebug === true,\n });\n\n if (this.shouldEmitCitations(mcpSessionId)) {\n const citations = this.buildRecallCitations(response);\n const guidance = buildCitationGuidance(citations);\n if (guidance.length > 0) {\n return {\n ...response,\n context: response.context + guidance,\n citations,\n };\n }\n }\n return response;\n }\n case \"engram.recall_explain\":\n return this.service.recallExplain({\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n });\n case \"engram.day_summary\":\n return this.service.daySummary({\n memories: typeof args.memories === \"string\" ? args.memories : \"\",\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n });\n case \"engram.memory_governance_run\":\n return this.service.governanceRun({\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n mode: args.mode === \"apply\" ? \"apply\" : \"shadow\",\n recentDays: typeof args.recentDays === \"number\" && Number.isFinite(args.recentDays) ? args.recentDays : undefined,\n maxMemories: typeof args.maxMemories === \"number\" && Number.isFinite(args.maxMemories) ? args.maxMemories : undefined,\n batchSize: typeof args.batchSize === \"number\" && Number.isFinite(args.batchSize) ? args.batchSize : undefined,\n authenticatedPrincipal: effectivePrincipal,\n }, effectivePrincipal);\n case \"engram.procedure_mining_run\":\n return this.service.procedureMiningRun(\n {\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n authenticatedPrincipal: effectivePrincipal,\n },\n effectivePrincipal,\n );\n case \"engram.memory_get\":\n return this.service.memoryGet(\n typeof args.memoryId === \"string\" ? args.memoryId : \"\",\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n effectivePrincipal,\n );\n case \"engram.memory_timeline\": {\n const limit = typeof args.limit === \"number\" && Number.isFinite(args.limit) ? args.limit : 200;\n return this.service.memoryTimeline(\n typeof args.memoryId === \"string\" ? args.memoryId : \"\",\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n limit,\n effectivePrincipal,\n );\n }\n case \"engram.memory_store\":\n return this.service.memoryStore({\n schemaVersion: typeof args.schemaVersion === \"number\" ? args.schemaVersion : undefined,\n idempotencyKey: typeof args.idempotencyKey === \"string\" ? args.idempotencyKey : undefined,\n dryRun: args.dryRun === true,\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n authenticatedPrincipal: effectivePrincipal,\n content: typeof args.content === \"string\" ? args.content : \"\",\n category: typeof args.category === \"string\" ? args.category : undefined,\n confidence: typeof args.confidence === \"number\" ? args.confidence : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n tags: Array.isArray(args.tags) ? args.tags.filter((tag): tag is string => typeof tag === \"string\") : undefined,\n entityRef: typeof args.entityRef === \"string\" ? args.entityRef : undefined,\n ttl: typeof args.ttl === \"string\" ? args.ttl : undefined,\n sourceReason: typeof args.sourceReason === \"string\" ? args.sourceReason : undefined,\n });\n case \"engram.suggestion_submit\":\n return this.service.suggestionSubmit({\n schemaVersion: typeof args.schemaVersion === \"number\" ? args.schemaVersion : undefined,\n idempotencyKey: typeof args.idempotencyKey === \"string\" ? args.idempotencyKey : undefined,\n dryRun: args.dryRun === true,\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n authenticatedPrincipal: effectivePrincipal,\n content: typeof args.content === \"string\" ? args.content : \"\",\n category: typeof args.category === \"string\" ? args.category : undefined,\n confidence: typeof args.confidence === \"number\" ? args.confidence : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n tags: Array.isArray(args.tags) ? args.tags.filter((tag): tag is string => typeof tag === \"string\") : undefined,\n entityRef: typeof args.entityRef === \"string\" ? args.entityRef : undefined,\n ttl: typeof args.ttl === \"string\" ? args.ttl : undefined,\n sourceReason: typeof args.sourceReason === \"string\" ? args.sourceReason : undefined,\n });\n case \"engram.entity_get\":\n return this.service.entityGet(\n typeof args.name === \"string\" ? args.name : \"\",\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n );\n case \"engram.review_queue_list\":\n return this.service.reviewQueue(\n typeof args.runId === \"string\" ? args.runId : undefined,\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n effectivePrincipal,\n );\n case \"engram.observe\":\n return this.service.observe({\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : \"\",\n messages: Array.isArray(args.messages) ? args.messages : [],\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n authenticatedPrincipal: effectivePrincipal,\n skipExtraction: args.skipExtraction === true,\n });\n case \"engram.lcm_search\":\n return this.service.lcmSearch({\n query: typeof args.query === \"string\" ? args.query : \"\",\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n limit: typeof args.limit === \"number\" && Number.isFinite(args.limit) ? args.limit : undefined,\n authenticatedPrincipal: effectivePrincipal,\n });\n // ── Continuity / Identity tools ───────────────────────────────────\n case \"engram.continuity_audit_generate\":\n return this.service.continuityAuditGenerate({\n period: args.period === \"monthly\" ? \"monthly\" : args.period === \"weekly\" ? \"weekly\" : undefined,\n key: typeof args.key === \"string\" ? args.key : undefined,\n });\n case \"engram.continuity_incident_open\":\n return this.service.continuityIncidentOpen({\n symptom: typeof args.symptom === \"string\" ? args.symptom : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n triggerWindow: typeof args.triggerWindow === \"string\" ? args.triggerWindow : undefined,\n suspectedCause: typeof args.suspectedCause === \"string\" ? args.suspectedCause : undefined,\n });\n case \"engram.continuity_incident_close\":\n return this.service.continuityIncidentClose({\n id: typeof args.id === \"string\" ? args.id : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n fixApplied: typeof args.fixApplied === \"string\" ? args.fixApplied : \"\",\n verificationResult: typeof args.verificationResult === \"string\" ? args.verificationResult : \"\",\n preventiveRule: typeof args.preventiveRule === \"string\" ? args.preventiveRule : undefined,\n });\n case \"engram.continuity_incident_list\":\n return this.service.continuityIncidentList({\n state: args.state === \"closed\" ? \"closed\" : args.state === \"all\" ? \"all\" : args.state === \"open\" ? \"open\" : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n limit: typeof args.limit === \"number\" ? args.limit : undefined,\n });\n case \"engram.continuity_loop_add_or_update\":\n return this.service.continuityLoopAddOrUpdate({\n id: typeof args.id === \"string\" ? args.id : \"\",\n cadence: (args.cadence as \"daily\" | \"weekly\" | \"monthly\" | \"quarterly\") ?? \"weekly\",\n purpose: typeof args.purpose === \"string\" ? args.purpose : \"\",\n status: (args.status as \"active\" | \"paused\" | \"retired\") ?? \"active\",\n killCondition: typeof args.killCondition === \"string\" ? args.killCondition : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n lastReviewed: typeof args.lastReviewed === \"string\" ? args.lastReviewed : undefined,\n notes: typeof args.notes === \"string\" ? args.notes : undefined,\n });\n case \"engram.continuity_loop_review\":\n return this.service.continuityLoopReview({\n id: typeof args.id === \"string\" ? args.id : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n status: args.status === \"active\" || args.status === \"paused\" || args.status === \"retired\" ? args.status : undefined,\n notes: typeof args.notes === \"string\" ? args.notes : undefined,\n reviewedAt: typeof args.reviewedAt === \"string\" ? args.reviewedAt : undefined,\n });\n case \"engram.identity_anchor_get\":\n return this.service.identityAnchorGet({\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n });\n case \"engram.identity_anchor_update\":\n return this.service.identityAnchorUpdate({\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n identityTraits: typeof args.identityTraits === \"string\" ? args.identityTraits : undefined,\n communicationPreferences: typeof args.communicationPreferences === \"string\" ? args.communicationPreferences : undefined,\n operatingPrinciples: typeof args.operatingPrinciples === \"string\" ? args.operatingPrinciples : undefined,\n continuityNotes: typeof args.continuityNotes === \"string\" ? args.continuityNotes : undefined,\n });\n case \"engram.memory_identity\":\n return this.service.memoryIdentity({\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n });\n // ── Work Layer tools ──────────────────────────────────────────────\n case \"engram.work_task\":\n return this.service.workTask({\n action: (args.action as any) ?? \"list\",\n id: typeof args.id === \"string\" ? args.id : undefined,\n title: typeof args.title === \"string\" ? args.title : undefined,\n description: typeof args.description === \"string\" ? args.description : undefined,\n status: typeof args.status === \"string\" ? args.status : undefined,\n priority: typeof args.priority === \"string\" ? args.priority : undefined,\n owner: typeof args.owner === \"string\" ? args.owner : undefined,\n assignee: typeof args.assignee === \"string\" ? args.assignee : undefined,\n projectId: typeof args.projectId === \"string\" ? args.projectId : undefined,\n tags: Array.isArray(args.tags) ? args.tags.filter((x: unknown): x is string => typeof x === \"string\") : undefined,\n dueAt: typeof args.dueAt === \"string\" ? args.dueAt : undefined,\n });\n case \"engram.work_project\":\n return this.service.workProject({\n action: (args.action as any) ?? \"list\",\n id: typeof args.id === \"string\" ? args.id : undefined,\n name: typeof args.name === \"string\" ? args.name : undefined,\n description: typeof args.description === \"string\" ? args.description : undefined,\n status: typeof args.status === \"string\" ? args.status : undefined,\n owner: typeof args.owner === \"string\" ? args.owner : undefined,\n tags: Array.isArray(args.tags) ? args.tags.filter((x: unknown): x is string => typeof x === \"string\") : undefined,\n taskId: typeof args.taskId === \"string\" ? args.taskId : undefined,\n projectId: typeof args.projectId === \"string\" ? args.projectId : undefined,\n });\n case \"engram.work_board\":\n return this.service.workBoard({\n action: (args.action as any) ?? \"export_markdown\",\n projectId: typeof args.projectId === \"string\" ? args.projectId : undefined,\n snapshotJson: typeof args.snapshotJson === \"string\" ? args.snapshotJson : undefined,\n linkToMemory: args.linkToMemory === true,\n });\n // ── Shared Context / Compounding tools ─────────────────────────\n case \"engram.shared_context_write_output\":\n return this.service.sharedContextWriteOutput({\n agentId: typeof args.agentId === \"string\" ? args.agentId : \"\",\n title: typeof args.title === \"string\" ? args.title : \"\",\n content: typeof args.content === \"string\" ? args.content : \"\",\n });\n case \"engram.shared_feedback_record\":\n return this.service.sharedFeedbackRecord({\n agent: typeof args.agent === \"string\" ? args.agent : \"\",\n decision: (args.decision as any) ?? \"approved\",\n reason: typeof args.reason === \"string\" ? args.reason : \"\",\n date: typeof args.date === \"string\" ? args.date : undefined,\n learning: typeof args.learning === \"string\" ? args.learning : undefined,\n outcome: typeof args.outcome === \"string\" ? args.outcome : undefined,\n severity: args.severity === \"low\" || args.severity === \"medium\" || args.severity === \"high\" ? args.severity : undefined,\n confidence: typeof args.confidence === \"number\" ? args.confidence : undefined,\n workflow: typeof args.workflow === \"string\" ? args.workflow : undefined,\n tags: Array.isArray(args.tags) ? args.tags.filter((x: unknown): x is string => typeof x === \"string\") : undefined,\n evidenceWindowStart: typeof args.evidenceWindowStart === \"string\" ? args.evidenceWindowStart : undefined,\n evidenceWindowEnd: typeof args.evidenceWindowEnd === \"string\" ? args.evidenceWindowEnd : undefined,\n refs: Array.isArray(args.refs) ? args.refs.filter((x: unknown): x is string => typeof x === \"string\") : undefined,\n });\n case \"engram.shared_priorities_append\":\n return this.service.sharedPrioritiesAppend({\n agentId: typeof args.agentId === \"string\" ? args.agentId : \"\",\n text: typeof args.text === \"string\" ? args.text : \"\",\n });\n case \"engram.shared_context_cross_signals_run\":\n return this.service.sharedContextCrossSignalsRun({\n date: typeof args.date === \"string\" ? args.date : undefined,\n });\n case \"engram.shared_context_curate_daily\":\n return this.service.sharedContextCurateDaily({\n date: typeof args.date === \"string\" ? args.date : undefined,\n });\n case \"engram.compounding_weekly_synthesize\":\n return this.service.compoundingWeeklySynthesize({\n weekId: typeof args.weekId === \"string\" ? args.weekId : undefined,\n });\n case \"engram.compounding_promote_candidate\":\n return this.service.compoundingPromoteCandidate({\n weekId: typeof args.weekId === \"string\" ? args.weekId : \"\",\n candidateId: typeof args.candidateId === \"string\" ? args.candidateId : \"\",\n dryRun: args.dryRun === true,\n });\n // ── Compression Guidelines tools ───────────────────────────────────\n case \"engram.compression_guidelines_optimize\":\n return this.service.compressionGuidelinesOptimize({\n dryRun: args.dryRun === true,\n eventLimit: typeof args.eventLimit === \"number\" ? args.eventLimit : undefined,\n });\n case \"engram.compression_guidelines_activate\":\n return this.service.compressionGuidelinesActivate({\n expectedContentHash: typeof args.expectedContentHash === \"string\" ? args.expectedContentHash : undefined,\n expectedGuidelineVersion: typeof args.expectedGuidelineVersion === \"number\" ? args.expectedGuidelineVersion : undefined,\n });\n // ── Memory search & debug tools ──────────────────────────────────\n case \"engram.memory_search\":\n return this.service.memorySearch({\n query: typeof args.query === \"string\" ? args.query : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n maxResults: typeof args.maxResults === \"number\" && Number.isFinite(args.maxResults) ? args.maxResults : undefined,\n collection: typeof args.collection === \"string\" ? args.collection : undefined,\n principal: effectivePrincipal,\n });\n case \"engram.memory_profile\":\n return this.service.memoryProfile(\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n effectivePrincipal,\n );\n case \"engram.memory_entities_list\":\n return this.service.memoryEntitiesList(\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n effectivePrincipal,\n );\n case \"engram.memory_questions\":\n return this.service.memoryQuestions(\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n effectivePrincipal,\n );\n case \"engram.memory_last_recall\":\n return this.service.lastRecallSnapshot(\n typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n );\n case \"engram.memory_intent_debug\":\n return this.service.intentDebug(\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n );\n case \"engram.memory_qmd_debug\":\n return this.service.qmdDebug(\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n );\n case \"engram.memory_graph_explain\":\n return this.service.graphExplainLastRecall(\n typeof args.namespace === \"string\" ? args.namespace : undefined,\n );\n case \"engram.memory_feedback\":\n return this.service.memoryFeedback({\n memoryId: typeof args.memoryId === \"string\" ? args.memoryId : \"\",\n vote: args.vote === \"down\" ? \"down\" : \"up\",\n note: typeof args.note === \"string\" ? args.note : undefined,\n });\n case \"engram.memory_promote\":\n return this.service.memoryPromote({\n memoryId: typeof args.memoryId === \"string\" ? args.memoryId : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : undefined,\n });\n case \"engram.context_checkpoint\":\n return this.service.contextCheckpoint({\n sessionKey: typeof args.sessionKey === \"string\" ? args.sessionKey : \"\",\n context: typeof args.context === \"string\" ? args.context : \"\",\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n principal: effectivePrincipal,\n });\n // ── Daily Context Briefing (#370) ───────────────────────────────────\n case \"engram.briefing\": {\n // Validate the format value upfront — unsupported values (e.g. \"xml\")\n // must be rejected with a descriptive error rather than silently\n // falling back to the default format.\n const rawFormat = typeof args.format === \"string\" ? args.format : undefined;\n const formatErr = validateBriefingFormat(rawFormat);\n if (formatErr) throw new Error(formatErr);\n return this.service.briefing({\n since: typeof args.since === \"string\" ? args.since : undefined,\n focus: typeof args.focus === \"string\" ? args.focus : undefined,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n format: rawFormat as \"json\" | \"markdown\" | undefined,\n maxFollowups:\n typeof args.maxFollowups === \"number\" ? args.maxFollowups : undefined,\n principal: effectivePrincipal,\n });\n }\n // ── Contradiction Review (issue #520) ──────────────────────────────────\n case \"engram.review_list\":\n case \"remnic.review_list\": {\n const { listPairs } = await import(\"./contradiction/contradiction-review.js\");\n const filter = typeof args.filter === \"string\" ? args.filter as \"all\" | \"unresolved\" | \"contradicts\" | \"independent\" | \"duplicates\" | \"needs-user\" : \"unresolved\";\n const ns = typeof args.namespace === \"string\" ? args.namespace : undefined;\n const limit = typeof args.limit === \"number\" ? args.limit : 50;\n return listPairs(this.service.memoryDir, { filter, namespace: ns, limit });\n }\n case \"engram.review_resolve\":\n case \"remnic.review_resolve\": {\n const pairId = typeof args.pairId === \"string\" ? args.pairId : \"\";\n const verb = typeof args.verb === \"string\" ? args.verb : \"\";\n if (!pairId) throw new Error(\"pairId is required\");\n if (!verb) throw new Error(\"verb is required\");\n const { isValidResolutionVerb } = await import(\"./contradiction/resolution.js\");\n if (!isValidResolutionVerb(verb)) throw new Error(`Invalid verb: ${verb}. Must be one of: keep-a, keep-b, merge, both-valid, needs-more-context`);\n const { executeResolution } = await import(\"./contradiction/resolution.js\");\n return executeResolution(this.service.memoryDir, this.service.storageRef, pairId, verb);\n }\n case \"engram.contradiction_scan_run\":\n case \"remnic.contradiction_scan_run\": {\n const { runContradictionScan } = await import(\"./contradiction/contradiction-scan.js\");\n return runContradictionScan({\n storage: this.service.storageRef,\n config: this.service.configRef,\n memoryDir: this.service.memoryDir,\n embeddingLookup: this.service.embeddingLookupRef,\n localLlm: this.service.localLlmRef,\n fallbackLlm: this.service.fallbackLlmRef,\n namespace: typeof args.namespace === \"string\" ? args.namespace : undefined,\n });\n }\n default:\n throw new Error(`unknown tool: ${name}`);\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tokens.ts"],"sourcesContent":["/**\n * Token management for Remnic multi-connector auth.\n *\n * Manages per-connector tokens in ~/.remnic/tokens.json.\n * Each connector gets a unique token with a recognizable prefix.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\n\nexport interface TokenEntry {\n token: string;\n connector: string;\n createdAt: string;\n}\n\nexport interface TokenStore {\n tokens: TokenEntry[];\n}\n\nconst TOKEN_PREFIXES: Record<string, string> = {\n \"openclaw\": \"remnic_oc_\",\n \"claude-code\": \"remnic_cc_\",\n \"codex-cli\": \"remnic_cx_\",\n \"codex\": \"remnic_cx_\",\n \"hermes\": \"remnic_hm_\",\n \"replit\": \"remnic_rl_\",\n \"cursor\": \"remnic_cu_\",\n \"cline\": \"remnic_cl_\",\n \"github-copilot\": \"remnic_gh_\",\n \"roo-code\": \"remnic_rc_\",\n \"windsurf\": \"remnic_ws_\",\n \"amp\": \"remnic_am_\",\n \"generic-mcp\": \"remnic_gm_\",\n};\n\nfunction defaultTokensPath(): string {\n return path.join(process.env.HOME ?? \"~\", \".remnic\", \"tokens.json\");\n}\n\nfunction legacyTokensPath(): string {\n return path.join(process.env.HOME ?? \"~\", \".engram\", \"tokens.json\");\n}\n\nfunction resolveReadPath(tokensPath?: string): string {\n const primary = tokensPath ?? defaultTokensPath();\n if (tokensPath) return primary;\n if (fs.existsSync(primary)) return primary;\n const legacy = legacyTokensPath();\n return fs.existsSync(legacy) ? legacy : primary;\n}\n\nfunction ensureDir(filePath: string): void {\n const dir = path.dirname(filePath);\n fs.mkdirSync(dir, { recursive: true });\n}\n\nexport function loadTokenStore(tokensPath?: string): TokenStore {\n const p = resolveReadPath(tokensPath);\n try {\n const raw = JSON.parse(fs.readFileSync(p, \"utf8\"));\n if (Array.isArray(raw.tokens)) {\n return { tokens: raw.tokens };\n }\n // Migrate legacy flat-map format: { \"connector\": \"token_value\", ... }\n if (typeof raw === \"object\" && raw !== null && !Array.isArray(raw)) {\n const migrated: TokenEntry[] = [];\n for (const [key, value] of Object.entries(raw)) {\n if (key === \"tokens\") continue; // skip if tokens key exists but isn't array\n if (typeof value === \"string\" && value.length > 0) {\n migrated.push({ token: value, connector: key, createdAt: new Date().toISOString() });\n }\n }\n if (migrated.length > 0) {\n const store: TokenStore = { tokens: migrated };\n // Auto-migrate: rewrite in new format (best-effort, don't lose tokens on write failure)\n try {\n saveTokenStore(store, tokensPath);\n } catch {\n // Migration write failed (e.g., read-only fs) — still return parsed tokens\n }\n return store;\n }\n }\n return { tokens: [] };\n } catch {\n return { tokens: [] };\n }\n}\n\nexport function saveTokenStore(store: TokenStore, tokensPath?: string): void {\n const p = tokensPath ?? defaultTokensPath();\n ensureDir(p);\n fs.writeFileSync(p, JSON.stringify(store, null, 2) + \"\\n\", { mode: 0o600 });\n // Tighten permissions on pre-existing files (writeFileSync mode only applies to new files)\n try { fs.chmodSync(p, 0o600); } catch { /* ignore on platforms without chmod */ }\n}\n\n/**\n * Build a TokenEntry candidate WITHOUT saving it to the store.\n * Callers use this when they need to defer the save until after a\n * dependent write (e.g. Hermes config.yaml) succeeds — see\n * commitTokenEntry() to persist the candidate.\n */\nexport function buildTokenEntry(connector: string): TokenEntry {\n const prefix = TOKEN_PREFIXES[connector] ?? \"remnic_xx_\";\n const token = prefix + randomBytes(24).toString(\"hex\");\n return {\n token,\n connector,\n createdAt: new Date().toISOString(),\n };\n}\n\n/**\n * Persist a pre-built TokenEntry into the store, replacing any existing\n * entry for the same connector. Used together with buildTokenEntry() when\n * the caller wants to defer the save until after a dependent write succeeds.\n *\n * For transactional rollback, callers should snapshot the full store via\n * loadTokenStore() BEFORE calling commitTokenEntry() and restore it with\n * saveTokenStore() on failure. A full-store snapshot handles partial writes\n * of tokens.json atomically — single-entry restore via the return value is\n * insufficient because if this function throws during saveTokenStore, the\n * return statement never executes (UXJI/UXJT fix).\n */\nexport function commitTokenEntry(entry: TokenEntry, tokensPath?: string): void {\n const store = loadTokenStore(tokensPath);\n store.tokens = store.tokens.filter((t) => t.connector !== entry.connector);\n store.tokens.push(entry);\n saveTokenStore(store, tokensPath);\n}\n\nexport function generateToken(connector: string, tokensPath?: string): TokenEntry {\n const store = loadTokenStore(tokensPath);\n\n // Remove existing token for this connector\n store.tokens = store.tokens.filter((t) => t.connector !== connector);\n\n const entry = buildTokenEntry(connector);\n store.tokens.push(entry);\n saveTokenStore(store, tokensPath);\n return entry;\n}\n\nexport function listTokens(tokensPath?: string): TokenEntry[] {\n return loadTokenStore(tokensPath).tokens;\n}\n\nexport function revokeToken(connector: string, tokensPath?: string): boolean {\n const store = loadTokenStore(tokensPath);\n const before = store.tokens.length;\n store.tokens = store.tokens.filter((t) => t.connector !== connector);\n if (store.tokens.length < before) {\n saveTokenStore(store, tokensPath);\n return true;\n }\n return false;\n}\n\nexport function getAllValidTokens(tokensPath?: string): string[] {\n return loadTokenStore(tokensPath).tokens.map((t) => t.token);\n}\n\n// Cached token loader to avoid synchronous disk I/O on every HTTP request.\n// Re-reads tokens.json at most once per TTL interval (default 5s).\nconst TOKEN_CACHE_TTL_MS = 5_000;\nlet _cachedTokens: string[] = [];\nlet _cachedAt = 0;\nlet _cachedPath: string | undefined;\n\nexport function getAllValidTokensCached(tokensPath?: string): string[] {\n const now = Date.now();\n if (now - _cachedAt < TOKEN_CACHE_TTL_MS && tokensPath === _cachedPath) return _cachedTokens;\n _cachedTokens = getAllValidTokens(tokensPath);\n _cachedAt = now;\n _cachedPath = tokensPath;\n return _cachedTokens;\n}\n\nexport function resolveConnectorFromToken(token: string, tokensPath?: string): string | undefined {\n return loadTokenStore(tokensPath).tokens.find((t) => t.token === token)?.connector;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/taxonomy/resolver.ts"],"sourcesContent":["/**\n * Resolver decision tree for the MECE taxonomy.\n *\n * Given extracted content and its MemoryCategory, determines which\n * taxonomy category the knowledge should be filed under.\n */\n\nimport type { MemoryCategory } from \"../types.js\";\nimport type { ResolverDecision, Taxonomy, TaxonomyCategory } from \"./types.js\";\n\nconst DEFAULT_CATEGORY_ID = \"facts\";\n\n/**\n * Resolve a piece of content to a taxonomy category.\n *\n * Algorithm:\n * 1. Find all taxonomy categories whose `memoryCategories` include\n * the given `memoryCategory`.\n * 2. If exactly one match, return it with confidence 1.0.\n * 3. If multiple matches, pick the one with the lowest priority\n * number (highest precedence). Apply keyword heuristics from\n * filing rules as a secondary signal.\n * 4. If no match, fall back to the \"facts\" category (or first\n * category if \"facts\" is absent) with low confidence.\n * 5. Always populate `alternatives` with other plausible categories.\n */\nexport function resolveCategory(\n content: string,\n memoryCategory: MemoryCategory,\n taxonomy: Taxonomy,\n): ResolverDecision {\n const contentLower = content.toLowerCase();\n\n // Step 1: find matching categories\n const matches = taxonomy.categories.filter((cat) =>\n cat.memoryCategories.includes(memoryCategory),\n );\n\n if (matches.length === 0) {\n // No taxonomy category accepts this MemoryCategory — fall back\n const fallback =\n taxonomy.categories.find((c) => c.id === DEFAULT_CATEGORY_ID) ??\n taxonomy.categories[0];\n if (!fallback) {\n return {\n categoryId: DEFAULT_CATEGORY_ID,\n confidence: 0,\n reason: \"Taxonomy is empty; using default category\",\n alternatives: [],\n };\n }\n const alternatives = taxonomy.categories\n .filter((c) => c.id !== fallback.id)\n .map((c) => ({\n categoryId: c.id,\n reason: c.description,\n }));\n return {\n categoryId: fallback.id,\n confidence: 0.3,\n reason: `No taxonomy category maps to MemoryCategory \"${memoryCategory}\"; falling back to \"${fallback.name}\"`,\n alternatives,\n };\n }\n\n if (matches.length === 1) {\n const match = matches[0]!;\n const alternatives = taxonomy.categories\n .filter((c) => c.id !== match.id)\n .map((c) => ({\n categoryId: c.id,\n reason: c.description,\n }));\n return {\n categoryId: match.id,\n confidence: 1.0,\n reason: `Unique match: MemoryCategory \"${memoryCategory}\" maps to \"${match.name}\"`,\n alternatives,\n };\n }\n\n // Multiple matches — use filing rule keyword heuristics + priority\n const scored = matches.map((cat) => ({\n cat,\n keywordScore: computeKeywordScore(contentLower, cat),\n }));\n\n // Sort by keyword score descending, then priority ascending (lower wins)\n scored.sort((a, b) => {\n if (b.keywordScore !== a.keywordScore) return b.keywordScore - a.keywordScore;\n return a.cat.priority - b.cat.priority;\n });\n\n const best = scored[0]!;\n const runnerUp = scored[1];\n\n // Confidence is higher when keyword match clearly differentiates\n const confidence =\n best.keywordScore > 0 && (!runnerUp || best.keywordScore > runnerUp.keywordScore)\n ? 0.9\n : 0.7;\n\n const alternatives = taxonomy.categories\n .filter((c) => c.id !== best.cat.id)\n .map((c) => ({\n categoryId: c.id,\n reason: c.description,\n }));\n\n const reason =\n best.keywordScore > 0\n ? `Filing rules for \"${best.cat.name}\" matched content keywords (priority ${best.cat.priority})`\n : `Priority tie-break: \"${best.cat.name}\" has lowest priority number (${best.cat.priority})`;\n\n return {\n categoryId: best.cat.id,\n confidence,\n reason,\n alternatives,\n };\n}\n\n/**\n * Compute a simple keyword overlap score between content and\n * a category's filing rules + description.\n */\nfunction computeKeywordScore(contentLower: string, cat: TaxonomyCategory): number {\n let score = 0;\n const ruleText = [...cat.filingRules, cat.description]\n .join(\" \")\n .toLowerCase();\n\n // Extract meaningful words (3+ chars) from the rule text\n const keywords = ruleText\n .split(/[^a-z0-9]+/)\n .filter((w) => w.length >= 3);\n\n for (const kw of keywords) {\n if (contentLower.includes(kw)) {\n score += 1;\n }\n }\n return score;\n}\n"],"mappings":";AAUA,IAAM,sBAAsB;AAgBrB,SAAS,gBACd,SACA,gBACA,UACkB;AAClB,QAAM,eAAe,QAAQ,YAAY;AAGzC,QAAM,UAAU,SAAS,WAAW;AAAA,IAAO,CAAC,QAC1C,IAAI,iBAAiB,SAAS,cAAc;AAAA,EAC9C;AAEA,MAAI,QAAQ,WAAW,GAAG;AAExB,UAAM,WACJ,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,mBAAmB,KAC5D,SAAS,WAAW,CAAC;AACvB,QAAI,CAAC,UAAU;AACb,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,cAAc,CAAC;AAAA,MACjB;AAAA,IACF;AACA,UAAMA,gBAAe,SAAS,WAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,EAClC,IAAI,CAAC,OAAO;AAAA,MACX,YAAY,EAAE;AAAA,MACd,QAAQ,EAAE;AAAA,IACZ,EAAE;AACJ,WAAO;AAAA,MACL,YAAY,SAAS;AAAA,MACrB,YAAY;AAAA,MACZ,QAAQ,gDAAgD,cAAc,uBAAuB,SAAS,IAAI;AAAA,MAC1G,cAAAA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,QAAQ,QAAQ,CAAC;AACvB,UAAMA,gBAAe,SAAS,WAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,EAC/B,IAAI,CAAC,OAAO;AAAA,MACX,YAAY,EAAE;AAAA,MACd,QAAQ,EAAE;AAAA,IACZ,EAAE;AACJ,WAAO;AAAA,MACL,YAAY,MAAM;AAAA,MAClB,YAAY;AAAA,MACZ,QAAQ,iCAAiC,cAAc,cAAc,MAAM,IAAI;AAAA,MAC/E,cAAAA;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,IACnC;AAAA,IACA,cAAc,oBAAoB,cAAc,GAAG;AAAA,EACrD,EAAE;AAGF,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,QAAI,EAAE,iBAAiB,EAAE,aAAc,QAAO,EAAE,eAAe,EAAE;AACjE,WAAO,EAAE,IAAI,WAAW,EAAE,IAAI;AAAA,EAChC,CAAC;AAED,QAAM,OAAO,OAAO,CAAC;AACrB,QAAM,WAAW,OAAO,CAAC;AAGzB,QAAM,aACJ,KAAK,eAAe,MAAM,CAAC,YAAY,KAAK,eAAe,SAAS,gBAChE,MACA;AAEN,QAAM,eAAe,SAAS,WAC3B,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,EAClC,IAAI,CAAC,OAAO;AAAA,IACX,YAAY,EAAE;AAAA,IACd,QAAQ,EAAE;AAAA,EACZ,EAAE;AAEJ,QAAM,SACJ,KAAK,eAAe,IAChB,qBAAqB,KAAK,IAAI,IAAI,wCAAwC,KAAK,IAAI,QAAQ,MAC3F,wBAAwB,KAAK,IAAI,IAAI,iCAAiC,KAAK,IAAI,QAAQ;AAE7F,SAAO;AAAA,IACL,YAAY,KAAK,IAAI;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,oBAAoB,cAAsB,KAA+B;AAChF,MAAI,QAAQ;AACZ,QAAM,WAAW,CAAC,GAAG,IAAI,aAAa,IAAI,WAAW,EAClD,KAAK,GAAG,EACR,YAAY;AAGf,QAAM,WAAW,SACd,MAAM,YAAY,EAClB,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC;AAE9B,aAAW,MAAM,UAAU;AACzB,QAAI,aAAa,SAAS,EAAE,GAAG;AAC7B,eAAS;AAAA,IACX;AAAA,EACF;AACA,SAAO;AACT;","names":["alternatives"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/iso-timestamp.ts","../src/replay/types.ts","../src/routing/store.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// Shared ISO-8601 / RFC 3339 timestamp validation helpers.\n//\n// Two public entry points — a strict UTC-only parser used by the replay\n// pipeline, and a more permissive parser used by bulk-import adapters that\n// need to preserve source timezone offsets. Both share date-component,\n// offset-range, and round-trip validation so they cannot silently diverge.\n// ---------------------------------------------------------------------------\n\n// UTC-only: `...Z`, 0 or 3 fractional digits (replay canonical form).\nconst ISO_UTC_TIMESTAMP_RE =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?Z$/;\n\n// Lenient: variable-precision fractional seconds and `Z` or `[+-]HH:MM` offset.\nconst ISO_OFFSET_TIMESTAMP_RE =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$/;\n\n/**\n * Validate the date/time components of an ISO timestamp string.\n * Catches overflowed dates like Feb 31 that `Date.parse` silently normalizes.\n */\nfunction validateDateComponents(isoString: string): boolean {\n const match = isoString.match(\n /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})/,\n );\n if (!match) return false;\n const [, yStr, mStr, dStr, hStr, minStr, sStr] = match;\n const y = Number(yStr);\n const m = Number(mStr);\n const d = Number(dStr);\n const h = Number(hStr);\n const min = Number(minStr);\n const s = Number(sStr);\n if (m < 1 || m > 12) return false;\n if (d < 1 || d > 31) return false;\n if (h > 23 || min > 59 || s > 59) return false;\n // Validate day for the specific month (using Date(y, m, 0) to get days).\n const daysInMonth = new Date(y, m, 0).getDate();\n if (d > daysInMonth) return false;\n return true;\n}\n\n/**\n * Validate the timezone offset range if present.\n * Max offset is +/-14:00 per ISO 8601; minute part must be 0-59.\n */\nfunction validateOffset(isoString: string): boolean {\n const offsetMatch = isoString.match(/([+-])(\\d{2}):(\\d{2})$/);\n if (!offsetMatch) return true; // `Z` form, no offset to validate.\n const oh = Number(offsetMatch[2]);\n const om = Number(offsetMatch[3]);\n if (oh > 14 || om > 59) return false;\n // +14:00 is max; offsets like +14:30 are invalid.\n if (oh === 14 && om > 0) return false;\n return true;\n}\n\n/**\n * Normalize a `Z`-suffixed ISO timestamp to exactly three fractional digits so\n * the round-trip comparison against `Date.prototype.toISOString()` succeeds\n * regardless of input precision (or absence of a fractional part).\n */\nfunction normalizeUtcForComparison(value: string): string {\n const fracMatch = value.match(/\\.(\\d+)Z$/);\n if (fracMatch) {\n const ms = (fracMatch[1] + \"000\").slice(0, 3);\n return value.replace(/\\.\\d+Z$/, `.${ms}Z`);\n }\n return value.replace(/Z$/, \".000Z\");\n}\n\n/**\n * Strict UTC-only parser — accepts `YYYY-MM-DDTHH:MM:SS[.sss]Z`.\n * Returns milliseconds since epoch, or `null` if invalid.\n */\nexport function parseIsoUtcTimestamp(value: string): number | null {\n if (typeof value !== \"string\" || !ISO_UTC_TIMESTAMP_RE.test(value)) {\n return null;\n }\n const ts = Date.parse(value);\n if (!Number.isFinite(ts)) return null;\n if (!validateDateComponents(value)) return null;\n const roundTrip = new Date(ts).toISOString();\n if (roundTrip !== normalizeUtcForComparison(value)) return null;\n return ts;\n}\n\n/**\n * Lenient parser — accepts variable-precision fractional seconds and either\n * a `Z` suffix or a `[+-]HH:MM` offset. Returns milliseconds since epoch, or\n * `null` if the string is not a well-formed RFC 3339 timestamp.\n */\nexport function parseIsoOffsetTimestamp(value: string): number | null {\n if (typeof value !== \"string\" || !ISO_OFFSET_TIMESTAMP_RE.test(value)) {\n return null;\n }\n const ts = Date.parse(value);\n if (!Number.isFinite(ts)) return null;\n if (!validateDateComponents(value)) return null;\n if (!validateOffset(value)) return null;\n // For UTC timestamps (ending in `Z`), verify with a round-trip so that\n // overflowed UTC calendar dates cannot slip through.\n if (value.endsWith(\"Z\")) {\n const roundTrip = new Date(ts).toISOString();\n if (roundTrip !== normalizeUtcForComparison(value)) return null;\n }\n return ts;\n}\n","import { parseIsoUtcTimestamp } from \"../utils/iso-timestamp.js\";\n\nexport type ReplaySource = \"openclaw\" | \"claude\" | \"chatgpt\";\nexport type ReplayRole = \"user\" | \"assistant\";\n\nexport interface ReplayTurn {\n source: ReplaySource;\n sessionKey: string;\n role: ReplayRole;\n content: string;\n timestamp: string;\n externalId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface ReplayWarning {\n code: string;\n message: string;\n index?: number;\n}\n\nexport interface ReplayValidationIssue {\n code: string;\n message: string;\n index?: number;\n}\n\nexport interface ReplayParseOptions {\n from?: string;\n to?: string;\n defaultSessionKey?: string;\n strict?: boolean;\n}\n\nexport interface ReplayParseResult {\n turns: ReplayTurn[];\n warnings: ReplayWarning[];\n}\n\nexport interface ReplayNormalizer {\n source: ReplaySource;\n parse(input: unknown, options?: ReplayParseOptions): Promise<ReplayParseResult> | ReplayParseResult;\n}\n\nconst VALID_SOURCES: ReadonlySet<string> = new Set([\"openclaw\", \"claude\", \"chatgpt\"]);\nconst VALID_ROLES: ReadonlySet<string> = new Set([\"user\", \"assistant\"]);\nexport const REPLAY_UNKNOWN_SESSION_KEY = \"replay:unknown\";\n\nexport function isReplaySource(value: unknown): value is ReplaySource {\n return typeof value === \"string\" && VALID_SOURCES.has(value);\n}\n\nexport function isReplayRole(value: unknown): value is ReplayRole {\n return typeof value === \"string\" && VALID_ROLES.has(value);\n}\n\nexport function normalizeReplaySessionKey(value: unknown): string {\n if (typeof value !== \"string\") return REPLAY_UNKNOWN_SESSION_KEY;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : REPLAY_UNKNOWN_SESSION_KEY;\n}\n\n/**\n * Strict UTC-only ISO-8601 parser used by the replay pipeline.\n *\n * Delegates to the shared parser in `utils/iso-timestamp.ts` — do not\n * reimplement locally; extend that helper instead. Replay intentionally\n * rejects timezone-offset timestamps to keep canonical form consistent\n * across recorded transcripts.\n */\nexport function parseIsoTimestamp(value: string): number | null {\n return parseIsoUtcTimestamp(value);\n}\n\nexport function validateReplayTurn(turn: ReplayTurn, index?: number): ReplayValidationIssue[] {\n const issues: ReplayValidationIssue[] = [];\n if (!turn || typeof turn !== \"object\") {\n issues.push({\n code: \"turn.invalid\",\n message: \"Replay turn must be an object.\",\n index,\n });\n return issues;\n }\n\n if (!isReplayRole(turn.role)) {\n issues.push({\n code: \"turn.role.invalid\",\n message: `Replay role must be 'user' or 'assistant', received '${String(turn.role)}'.`,\n index,\n });\n }\n\n if (!isReplaySource(turn.source)) {\n issues.push({\n code: \"turn.source.invalid\",\n message: `Replay source must be 'openclaw', 'claude', or 'chatgpt', received '${String(turn.source)}'.`,\n index,\n });\n }\n\n if (!turn.sessionKey || typeof turn.sessionKey !== \"string\" || turn.sessionKey.trim().length === 0) {\n issues.push({\n code: \"turn.sessionKey.invalid\",\n message: \"Replay sessionKey is required.\",\n index,\n });\n }\n\n if (!turn.content || typeof turn.content !== \"string\" || turn.content.trim().length === 0) {\n issues.push({\n code: \"turn.content.invalid\",\n message: \"Replay content must be a non-empty string.\",\n index,\n });\n }\n\n if (!turn.timestamp || typeof turn.timestamp !== \"string\" || parseIsoTimestamp(turn.timestamp) === null) {\n issues.push({\n code: \"turn.timestamp.invalid\",\n message: `Replay timestamp must be a valid ISO timestamp, received '${String(turn.timestamp)}'.`,\n index,\n });\n }\n\n return issues;\n}\n","import { lstat, mkdir, readFile, realpath, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { log } from \"../logger.js\";\nimport { validateRouteTarget, type RouteRule, type RoutingEngineOptions } from \"./engine.js\";\n\ntype RoutingRulesState = {\n version: 1;\n updatedAt: string;\n rules: RouteRule[];\n};\n\nfunction defaultState(): RoutingRulesState {\n return {\n version: 1,\n updatedAt: new Date(0).toISOString(),\n rules: [],\n };\n}\n\nfunction stableRuleId(rule: Pick<RouteRule, \"patternType\" | \"pattern\" | \"priority\" | \"target\">): string {\n const seed = JSON.stringify({\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: rule.priority,\n target: rule.target,\n });\n return `route-${createHash(\"sha256\").update(seed).digest(\"hex\").slice(0, 12)}`;\n}\n\nfunction resolveStatePath(memoryDir: string, stateFile: string): string {\n const root = path.resolve(memoryDir);\n const defaultPath = path.join(root, \"state\", \"routing-rules.json\");\n if (path.isAbsolute(stateFile)) {\n const absolute = path.resolve(stateFile);\n return absolute.startsWith(root + path.sep) ? absolute : defaultPath;\n }\n const resolved = path.resolve(root, stateFile);\n return resolved.startsWith(root + path.sep) ? resolved : defaultPath;\n}\n\nfunction normalizeRule(rule: RouteRule, options?: RoutingEngineOptions): RouteRule | null {\n if (!rule || typeof rule !== \"object\") return null;\n if (rule.enabled === false) return null;\n if (rule.patternType !== \"keyword\" && rule.patternType !== \"regex\") return null;\n if (typeof rule.pattern !== \"string\" || rule.pattern.trim().length === 0) return null;\n if (typeof rule.priority !== \"number\" || !Number.isFinite(rule.priority)) return null;\n\n const targetValidation = validateRouteTarget(rule.target, options);\n if (!targetValidation.ok || !targetValidation.target) return null;\n\n const normalizedPriority = Math.trunc(rule.priority);\n const normalizedTarget = targetValidation.target;\n const id = typeof rule.id === \"string\" && rule.id.trim().length > 0\n ? rule.id.trim()\n : stableRuleId({\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: normalizedPriority,\n target: normalizedTarget,\n });\n return {\n id,\n patternType: rule.patternType,\n pattern: rule.pattern.trim(),\n priority: normalizedPriority,\n target: normalizedTarget,\n enabled: true,\n };\n}\n\nexport class RoutingRulesStore {\n private readonly memoryRoot: string;\n private readonly statePath: string;\n private readonly lockPath: string;\n private writeQueue: Promise<void> = Promise.resolve();\n\n constructor(memoryDir: string, stateFile = \"state/routing-rules.json\") {\n this.memoryRoot = path.resolve(memoryDir);\n this.statePath = resolveStatePath(memoryDir, stateFile);\n this.lockPath = `${this.statePath}.lock`;\n }\n\n async read(options?: RoutingEngineOptions): Promise<RouteRule[]> {\n try {\n const persisted = await this.readPersistedRules();\n return persisted\n .map((rule) => normalizeRule(rule, options))\n .filter((rule): rule is RouteRule => rule !== null);\n } catch {\n return [];\n }\n }\n\n async write(rules: RouteRule[], options?: RoutingEngineOptions): Promise<RouteRule[]> {\n return this.withWriteLock(async () => this.writeNormalized(rules, options));\n }\n\n async upsert(rule: RouteRule, options?: RoutingEngineOptions): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n const existing = await this.readPersistedRules();\n const normalized = normalizeRule(rule, options);\n if (!normalized) return existing;\n\n const next = existing.filter((entry) => entry.id !== normalized.id);\n next.push(normalized);\n return this.writeNormalized(next);\n });\n }\n\n async removeByPattern(pattern: string): Promise<RouteRule[]> {\n return this.withWriteLock(async () => {\n const trimmed = pattern.trim();\n const existing = await this.readPersistedRules();\n const next = existing.filter((entry) => entry.pattern !== trimmed);\n if (next.length === existing.length) return existing;\n return this.writeNormalized(next);\n });\n }\n\n async reset(): Promise<void> {\n await this.withWriteLock(async () => {\n const payload = defaultState();\n await this.assertStatePathScoped();\n await writeFile(this.statePath, JSON.stringify(payload, null, 2), \"utf-8\");\n });\n }\n\n private dedupeById(rules: RouteRule[]): RouteRule[] {\n const byId = new Map<string, RouteRule>();\n for (const rule of rules) {\n byId.set(rule.id, rule);\n }\n return Array.from(byId.values());\n }\n\n private async readPersistedRules(): Promise<RouteRule[]> {\n try {\n await this.assertStatePathScoped();\n const raw = await readFile(this.statePath, \"utf-8\");\n const parsed = JSON.parse(raw) as Partial<RoutingRulesState>;\n if (!parsed || typeof parsed !== \"object\" || !Array.isArray(parsed.rules)) return [];\n const normalized = parsed.rules\n .map((rule) => normalizeRule(rule))\n .filter((rule): rule is RouteRule => rule !== null);\n return this.dedupeById(normalized);\n } catch {\n return [];\n }\n }\n\n private async writeNormalized(rules: RouteRule[], options?: RoutingEngineOptions): Promise<RouteRule[]> {\n const normalized = this.dedupeById(\n rules\n .map((rule) => normalizeRule(rule, options))\n .filter((rule): rule is RouteRule => rule !== null),\n );\n\n const payload: RoutingRulesState = {\n version: 1,\n updatedAt: new Date().toISOString(),\n rules: normalized,\n };\n\n const tmpPath = `${this.statePath}.tmp-${process.pid}-${Date.now()}`;\n try {\n await this.assertStatePathScoped();\n await writeFile(tmpPath, JSON.stringify(payload, null, 2), \"utf-8\");\n await rename(tmpPath, this.statePath);\n } catch (err) {\n log.debug(`routing rules write failed: ${err}`);\n throw err;\n } finally {\n await rm(tmpPath, { force: true }).catch(() => {});\n }\n\n return normalized;\n }\n\n private async withWriteLock<T>(op: () => Promise<T>): Promise<T> {\n const previous = this.writeQueue;\n let release: () => void = () => {};\n this.writeQueue = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n let unlock: (() => Promise<void>) | null = null;\n try {\n unlock = await this.acquireFileLock();\n return await op();\n } finally {\n if (unlock) await unlock();\n release();\n }\n }\n\n private async acquireFileLock(): Promise<() => Promise<void>> {\n const start = Date.now();\n const staleMs = 30_000;\n const timeoutMs = 5_000;\n let unexpectedLockError: unknown = null;\n await this.assertStatePathScoped();\n await mkdir(path.dirname(this.lockPath), { recursive: true });\n\n while (Date.now() - start < timeoutMs) {\n try {\n await mkdir(this.lockPath);\n return async () => {\n try {\n await rm(this.lockPath, { recursive: true, force: true });\n } catch {\n // Fail-open: lock cleanup should not fail writes.\n }\n };\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") {\n unexpectedLockError = err;\n break;\n }\n try {\n const lockStat = await stat(this.lockPath);\n if (Date.now() - lockStat.mtimeMs > staleMs) {\n await rm(this.lockPath, { recursive: true, force: true });\n continue;\n }\n } catch {\n // Lock may have been released between stat/rm attempts.\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n if (unexpectedLockError) {\n throw unexpectedLockError;\n }\n throw new Error(`routing rules lock acquisition timed out after ${timeoutMs}ms`);\n }\n\n private async assertStatePathScoped(): Promise<void> {\n await mkdir(this.memoryRoot, { recursive: true });\n const canonicalRoot = await realpath(this.memoryRoot);\n const canonicalParent = await this.canonicalizePathWithoutCreating(path.dirname(this.statePath));\n const canonicalStatePath = path.join(canonicalParent, path.basename(this.statePath));\n if (!this.isPathInside(canonicalRoot, canonicalStatePath)) {\n throw new Error(`routing rules state path escaped memoryDir: ${canonicalStatePath}`);\n }\n await mkdir(path.dirname(this.statePath), { recursive: true });\n try {\n const stateStats = await lstat(this.statePath);\n if (stateStats.isSymbolicLink()) {\n const canonicalFile = await realpath(this.statePath);\n if (!this.isPathInside(canonicalRoot, canonicalFile)) {\n throw new Error(`routing rules state symlink escaped memoryDir: ${canonicalFile}`);\n }\n }\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n throw err;\n }\n }\n }\n\n private isPathInside(root: string, candidate: string): boolean {\n const normalizedRoot = path.resolve(root);\n const normalizedCandidate = path.resolve(candidate);\n if (normalizedCandidate === normalizedRoot) return true;\n if (normalizedRoot === path.parse(normalizedRoot).root) {\n return normalizedCandidate.startsWith(normalizedRoot);\n }\n return normalizedCandidate.startsWith(`${normalizedRoot}${path.sep}`);\n }\n\n private async canonicalizePathWithoutCreating(targetPath: string): Promise<string> {\n const absoluteTarget = path.resolve(targetPath);\n let probe = absoluteTarget;\n while (true) {\n try {\n const canonicalProbe = await realpath(probe);\n const remainder = path.relative(probe, absoluteTarget);\n return path.resolve(canonicalProbe, remainder);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n throw err;\n }\n const parent = path.dirname(probe);\n if (parent === probe) {\n return absoluteTarget;\n }\n probe = parent;\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/explicit-capture.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { Orchestrator } from \"./orchestrator.js\";\nimport { isSafeRouteNamespace } from \"./routing/engine.js\";\nimport { sanitizeMemoryContent } from \"./sanitize.js\";\nimport { ContentHashIndex } from \"./storage.js\";\nimport type { CaptureMode, MemoryCategory, MemoryLifecycleEvent, PluginConfig } from \"./types.js\";\n\nexport type ExplicitCaptureInput = {\n content: string;\n category?: string;\n confidence?: number;\n namespace?: string;\n tags?: string[];\n entityRef?: string;\n ttl?: string;\n sourceReason?: string;\n};\n\nexport type ValidExplicitCapture = {\n content: string;\n category: MemoryCategory;\n confidence: number;\n namespace?: string;\n tags: string[];\n entityRef?: string;\n expiresAt?: string;\n sourceReason?: string;\n};\n\nexport type ExplicitCaptureSource = \"memory_store\" | \"memory_capture\" | \"suggestion_submit\" | \"inline\";\ntype ExplicitCaptureValidationMode = \"legacy_tool\" | \"strict_explicit\";\n\nconst INLINE_NOTE_RE = /<memory_note>\\s*([\\s\\S]*?)\\s*<\\/memory_note>/gi;\nconst INLINE_NOTE_MARKUP_RE = /<memory_note>\\s*[\\s\\S]*?\\s*<\\/memory_note>/i;\nconst INLINE_ALLOWED_CATEGORIES = new Set<MemoryCategory>([\n \"fact\",\n \"preference\",\n \"correction\",\n \"entity\",\n \"decision\",\n \"relationship\",\n \"principle\",\n \"commitment\",\n \"moment\",\n \"skill\",\n \"rule\",\n \"procedure\",\n]);\n\nconst SECRET_PATTERNS: RegExp[] = [\n /\\bsk-[A-Za-z0-9]{16,}\\b/,\n /\\bAKIA[0-9A-Z]{16}\\b/,\n /\\bBearer\\s+[A-Za-z0-9._-]{16,}\\b/i,\n /\\b(?:api[_-]?key|secret|token|password|passwd)\\s*[:=]\\s*[^\\s]{8,}\\b/i,\n /\\b(?:authorization)\\s*:\\s*[^\\s]{8,}\\b/i,\n];\nconst SECRET_REDACTION_PATTERNS: Array<{ pattern: RegExp; replacement: string }> = [\n { pattern: /\\bsk-[A-Za-z0-9]{16,}\\b/g, replacement: \"[redacted openai key]\" },\n { pattern: /\\bAKIA[0-9A-Z]{16}\\b/g, replacement: \"[redacted aws key]\" },\n { pattern: /\\bBearer\\s+[A-Za-z0-9._-]{16,}\\b/gi, replacement: \"Bearer [redacted token]\" },\n {\n pattern: /\\b(?:api[_-]?key|secret|token|password|passwd)\\s*[:=]\\s*[^\\s]{8,}\\b/gi,\n replacement: \"[redacted credential]\",\n },\n {\n pattern: /\\b(?:authorization)\\s*:\\s*[^\\s]{8,}\\b/gi,\n replacement: \"authorization: [redacted credential]\",\n },\n];\nconst EXPLICIT_CAPTURE_REVIEW_TAGS = [\"explicit-capture\", \"queued-review\"];\n\nfunction explicitCaptureActor(source: ExplicitCaptureSource): string {\n switch (source) {\n case \"inline\":\n return \"inline.memory_note\";\n case \"memory_store\":\n return \"tool.memory_store\";\n case \"suggestion_submit\":\n return \"tool.suggestion_submit\";\n default:\n return \"tool.memory_capture\";\n }\n}\n\nfunction asTrimmed(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction normalizeCaptureContent(value: string): string {\n return value\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction redactSecrets(value: string): string {\n let redacted = value;\n for (const { pattern, replacement } of SECRET_REDACTION_PATTERNS) {\n redacted = redacted.replace(pattern, replacement);\n }\n return redacted;\n}\n\nfunction normalizeExplicitCaptureError(error: unknown): string {\n if (error instanceof Error && error.message.trim().length > 0) return error.message.trim();\n const rendered = String(error).trim();\n return rendered.length > 0 ? rendered : \"explicit capture failed\";\n}\n\nfunction resolveExplicitCaptureReviewNamespace(\n orchestrator: Orchestrator,\n namespace: string | undefined,\n): string | undefined {\n const normalized = asTrimmed(namespace);\n if (!normalized) return undefined;\n return resolveExplicitCaptureNamespace(orchestrator, normalized);\n}\n\nfunction resolveExplicitCaptureNamespace(\n orchestrator: Orchestrator,\n namespace: string | undefined,\n): string | undefined {\n const normalized = asTrimmed(namespace);\n if (!normalized) return undefined;\n if (!orchestrator.config.namespacesEnabled) {\n if (normalized !== orchestrator.config.defaultNamespace) {\n throw new Error(`unsupported namespace: ${normalized}`);\n }\n return normalized;\n }\n const allowed = new Set([\n orchestrator.config.defaultNamespace,\n orchestrator.config.sharedNamespace,\n ...orchestrator.config.namespacePolicies.map((policy) => policy.name),\n ].map((value) => value.trim()).filter(Boolean));\n if (!allowed.has(normalized)) {\n throw new Error(`unsupported namespace: ${normalized}`);\n }\n return normalized;\n}\n\nfunction parseExplicitCaptureTtl(ttl: string | undefined): string | undefined {\n const raw = asTrimmed(ttl);\n if (!raw) return undefined;\n\n const absoluteMs = Date.parse(raw);\n if (Number.isFinite(absoluteMs)) {\n return new Date(absoluteMs).toISOString();\n }\n\n const relative = raw.match(/^(\\d+)\\s*([mhdw])$/i);\n if (!relative) {\n throw new Error(\"ttl must be an ISO-8601 timestamp or relative duration like 30m, 12h, 7d, or 2w\");\n }\n\n const amount = Number.parseInt(relative[1] ?? \"\", 10);\n const unit = (relative[2] ?? \"\").toLowerCase();\n if (!Number.isFinite(amount) || amount <= 0) {\n throw new Error(\"ttl duration must be a positive integer\");\n }\n\n const multiplier =\n unit === \"m\" ? 60_000\n : unit === \"h\" ? 60 * 60_000\n : unit === \"d\" ? 24 * 60 * 60_000\n : 7 * 24 * 60 * 60_000;\n return new Date(Date.now() + amount * multiplier).toISOString();\n}\n\nfunction parseInlineNote(block: string): ExplicitCaptureInput | null {\n const lines = block.replace(/\\r/g, \"\").split(\"\\n\");\n const note: Partial<ExplicitCaptureInput> = {};\n let idx = 0;\n\n while (idx < lines.length) {\n const rawLine = lines[idx] ?? \"\";\n const line = rawLine.trim();\n idx += 1;\n if (line.length === 0) continue;\n const colonIdx = line.indexOf(\":\");\n if (colonIdx < 0) continue;\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n\n if (key === \"content\" && value === \"|\") {\n const contentLines: string[] = [];\n while (idx < lines.length) {\n const next = lines[idx] ?? \"\";\n if (next.startsWith(\" \") || next.startsWith(\"\\t\")) {\n contentLines.push(next.replace(/^( |\\t)/, \"\"));\n idx += 1;\n continue;\n }\n if (next.trim().length === 0) {\n contentLines.push(\"\");\n idx += 1;\n continue;\n }\n break;\n }\n note.content = contentLines.join(\"\\n\").trim();\n continue;\n }\n\n switch (key) {\n case \"content\":\n note.content = value;\n break;\n case \"category\":\n note.category = value;\n break;\n case \"confidence\":\n note.confidence = Number.parseFloat(value);\n break;\n case \"namespace\":\n note.namespace = value;\n break;\n case \"tags\":\n note.tags = value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean);\n break;\n case \"entityRef\":\n note.entityRef = value;\n break;\n case \"ttl\":\n note.ttl = value;\n break;\n case \"sourceReason\":\n note.sourceReason = value;\n break;\n default:\n break;\n }\n }\n\n return asTrimmed(note.content) ? (note as ExplicitCaptureInput) : null;\n}\n\nexport function parseInlineExplicitCaptureNotes(text: string): ExplicitCaptureInput[] {\n const notes: ExplicitCaptureInput[] = [];\n for (const match of text.matchAll(INLINE_NOTE_RE)) {\n const parsed = parseInlineNote(match[1] ?? \"\");\n if (parsed) notes.push(parsed);\n }\n return notes;\n}\n\nexport function hasInlineExplicitCaptureMarkup(text: string): boolean {\n return INLINE_NOTE_MARKUP_RE.test(text);\n}\n\nexport function stripInlineExplicitCaptureNotes(text: string): string {\n return text.replace(INLINE_NOTE_RE, \"\").trim();\n}\n\nexport function validateExplicitCaptureInput(\n input: ExplicitCaptureInput,\n mode: ExplicitCaptureValidationMode = \"strict_explicit\",\n): ValidExplicitCapture {\n const content = asTrimmed(input.content);\n if (!content) throw new Error(\"content is required\");\n if (mode === \"strict_explicit\") {\n if (content.length < 10) throw new Error(\"content must be at least 10 characters\");\n if (content.length > 4000) throw new Error(\"content must be 4000 characters or fewer\");\n }\n if (/<memory_note>/i.test(content) || /<\\/memory_note>/i.test(content)) {\n throw new Error(\"nested memory_note blocks are not allowed\");\n }\n\n const category = (asTrimmed(input.category) ?? \"fact\") as MemoryCategory;\n if (!INLINE_ALLOWED_CATEGORIES.has(category)) {\n throw new Error(`unsupported category: ${input.category ?? category}`);\n }\n\n const sanitized = sanitizeMemoryContent(content);\n if (!sanitized.clean) {\n throw new Error(\"content failed memory sanitization\");\n }\n for (const pattern of SECRET_PATTERNS) {\n if (pattern.test(content)) {\n throw new Error(\"content appears to contain a secret or credential\");\n }\n }\n\n const confidence = Number.isFinite(input.confidence) ? Number(input.confidence) : 0.95;\n if (confidence < 0 || confidence > 1) {\n throw new Error(\"confidence must be between 0 and 1\");\n }\n const requestedNamespace = asTrimmed(input.namespace);\n if (requestedNamespace && !isSafeRouteNamespace(requestedNamespace)) {\n throw new Error(`unsafe namespace: ${requestedNamespace}`);\n }\n const expiresAt = parseExplicitCaptureTtl(input.ttl);\n\n return {\n content,\n category,\n confidence,\n namespace: asTrimmed(input.namespace),\n tags: Array.from(new Set((input.tags ?? []).map((tag) => tag.trim()).filter(Boolean))),\n entityRef: asTrimmed(input.entityRef),\n expiresAt,\n sourceReason: asTrimmed(input.sourceReason),\n };\n}\n\nasync function findDuplicateExplicitCapture(\n orchestrator: Orchestrator,\n resolvedNamespace: string | undefined,\n candidate: ValidExplicitCapture,\n): Promise<string | null> {\n const storage = await orchestrator.getStorage(resolvedNamespace);\n if (\n candidate.category === \"fact\"\n && typeof (storage as { hasFactContentHash?: (content: string) => Promise<boolean> }).hasFactContentHash === \"function\"\n ) {\n try {\n const hasHash = await (storage as { hasFactContentHash: (content: string) => Promise<boolean> }).hasFactContentHash(\n candidate.content,\n );\n if (!hasHash) {\n const authoritative =\n typeof (storage as { isFactContentHashAuthoritative?: () => Promise<boolean> | boolean }).isFactContentHashAuthoritative\n === \"function\"\n ? await (storage as { isFactContentHashAuthoritative: () => Promise<boolean> | boolean })\n .isFactContentHashAuthoritative()\n : false;\n if (authoritative) return null;\n }\n } catch (err) {\n // Fail open: hash index is only an optimization, so fall back to the full corpus scan.\n void err;\n }\n }\n const existing = await storage.readAllMemories();\n const normalizedCandidate = normalizeCaptureContent(candidate.content);\n const match = existing.find((memory) => {\n const status = memory.frontmatter.status ?? \"active\";\n if (status !== \"active\") return false;\n if (memory.frontmatter.category !== candidate.category) return false;\n return normalizeCaptureContent(memory.content) === normalizedCandidate;\n });\n return match?.frontmatter.id ?? null;\n}\n\nexport async function persistExplicitCapture(\n orchestrator: Orchestrator,\n candidate: ValidExplicitCapture,\n source: ExplicitCaptureSource,\n): Promise<{ id: string; duplicateOf?: string }> {\n const resolvedNamespace = resolveExplicitCaptureNamespace(orchestrator, candidate.namespace);\n const duplicateOf = await findDuplicateExplicitCapture(orchestrator, resolvedNamespace, candidate);\n if (duplicateOf) {\n return { id: duplicateOf, duplicateOf };\n }\n\n const storage = await orchestrator.getStorage(resolvedNamespace);\n const id = await storage.writeMemory(candidate.category, candidate.content, {\n confidence: candidate.confidence,\n tags: candidate.tags,\n entityRef: candidate.entityRef,\n expiresAt: candidate.expiresAt,\n source: source === \"inline\" ? \"explicit-inline\" : \"explicit\",\n });\n\n const created = new Date().toISOString();\n const event: MemoryLifecycleEvent = {\n eventId: `mle-${randomUUID()}`,\n memoryId: id,\n eventType: \"explicit_capture_accepted\",\n timestamp: created,\n actor: explicitCaptureActor(source),\n reasonCode: candidate.sourceReason,\n ruleVersion: \"explicit-capture.v1\",\n };\n await storage.appendMemoryLifecycleEvents([event]);\n\n return { id };\n}\n\nfunction buildExplicitCaptureReviewContent(input: ExplicitCaptureInput, reason: string): string {\n const requestedContent = asTrimmed(input.content);\n const sanitized = sanitizeMemoryContent(redactSecrets(requestedContent ?? \"[empty explicit capture]\"));\n const safeContent = sanitized.text.trim().length > 0 ? sanitized.text.trim() : \"[empty explicit capture]\";\n const lines = [\n \"Explicit capture queued for review.\",\n \"\",\n `Reason: ${reason}`,\n \"\",\n \"Submitted content:\",\n safeContent,\n ];\n const metadata = [\n input.category ? `Requested category: ${input.category}` : undefined,\n input.namespace ? `Requested namespace: ${input.namespace}` : undefined,\n input.entityRef ? `Requested entityRef: ${input.entityRef}` : undefined,\n input.ttl ? `Requested ttl: ${input.ttl}` : undefined,\n input.sourceReason ? `Requested sourceReason: ${input.sourceReason}` : undefined,\n input.tags && input.tags.length > 0 ? `Requested tags: ${input.tags.join(\", \")}` : undefined,\n ].filter((entry): entry is string => typeof entry === \"string\" && entry.length > 0);\n if (metadata.length > 0) {\n lines.push(\"\", ...metadata);\n }\n return lines.join(\"\\n\");\n}\n\nasync function findQueuedExplicitCaptureDuplicate(\n orchestrator: Orchestrator,\n namespace: string | undefined,\n content: string,\n): Promise<string | null> {\n const storage = await orchestrator.getStorage(namespace);\n const existing = await storage.readAllMemories();\n const normalized = normalizeCaptureContent(content);\n const match = existing.find((memory) => {\n const status = memory.frontmatter.status ?? \"active\";\n if (status !== \"pending_review\") return false;\n if (!(memory.frontmatter.tags ?? []).includes(\"queued-review\")) return false;\n return normalizeCaptureContent(memory.content) === normalized;\n });\n return match?.frontmatter.id ?? null;\n}\n\nexport async function queueExplicitCaptureForReview(\n orchestrator: Orchestrator,\n input: ExplicitCaptureInput,\n source: ExplicitCaptureSource,\n error: unknown,\n): Promise<{ id: string; duplicateOf?: string }> {\n const reason = normalizeExplicitCaptureError(error);\n const requestedNamespace = asTrimmed(input.namespace);\n const queueNamespace = resolveExplicitCaptureReviewNamespace(orchestrator, requestedNamespace);\n const content = buildExplicitCaptureReviewContent(input, reason);\n const duplicateOf = await findQueuedExplicitCaptureDuplicate(orchestrator, queueNamespace, content);\n if (duplicateOf) {\n return { id: duplicateOf, duplicateOf };\n }\n\n const requestedCategory = asTrimmed(input.category);\n const reviewCategory = requestedCategory && INLINE_ALLOWED_CATEGORIES.has(requestedCategory as MemoryCategory)\n ? requestedCategory as MemoryCategory\n : \"fact\";\n const requestedTags = Array.isArray(input.tags)\n ? input.tags.map((tag) => tag.trim()).filter(Boolean)\n : [];\n const storage = await orchestrator.getStorage(queueNamespace);\n const id = await storage.writeMemory(reviewCategory, content, {\n confidence: 0.2,\n tags: Array.from(new Set([...EXPLICIT_CAPTURE_REVIEW_TAGS, ...requestedTags])),\n entityRef: asTrimmed(input.entityRef),\n source: source === \"inline\" ? \"explicit-inline-review\" : \"explicit-review\",\n });\n const created = await storage.getMemoryById(id);\n if (created) {\n await storage.writeMemoryFrontmatter(created, {\n status: \"pending_review\",\n updated: new Date().toISOString(),\n }, {\n actor: explicitCaptureActor(source),\n reasonCode: reason,\n ruleVersion: \"explicit-capture.v1\",\n });\n }\n const event: MemoryLifecycleEvent = {\n eventId: `mle-${randomUUID()}`,\n memoryId: id,\n eventType: \"explicit_capture_queued\",\n timestamp: new Date().toISOString(),\n actor: explicitCaptureActor(source),\n reasonCode: reason,\n ruleVersion: \"explicit-capture.v1\",\n };\n await storage.appendMemoryLifecycleEvents([event]);\n return { id };\n}\n\nexport function shouldSkipImplicitExtraction(cfg: Pick<PluginConfig, \"captureMode\">): boolean {\n return cfg.captureMode === \"explicit\";\n}\n\nexport function shouldProcessInlineExplicitCapture(cfg: Pick<PluginConfig, \"captureMode\">): boolean {\n return cfg.captureMode !== \"implicit\";\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/routing/engine.ts"],"sourcesContent":["import type { MemoryCategory } from \"../types.js\";\n\nexport type RoutePatternType = \"regex\" | \"keyword\";\n\nexport interface RouteTarget {\n category?: MemoryCategory;\n namespace?: string;\n}\n\nexport interface RouteRule {\n id: string;\n patternType: RoutePatternType;\n pattern: string;\n priority: number;\n target: RouteTarget;\n enabled?: boolean;\n}\n\nexport interface RoutingEngineOptions {\n allowedNamespaces?: string[];\n allowedCategories?: MemoryCategory[];\n}\n\nexport interface RouteSelection {\n rule: RouteRule;\n target: RouteTarget;\n}\n\nconst DEFAULT_CATEGORIES: readonly MemoryCategory[] = [\n \"fact\",\n \"preference\",\n \"correction\",\n \"entity\",\n \"decision\",\n \"relationship\",\n \"principle\",\n \"commitment\",\n \"moment\",\n \"skill\",\n \"rule\",\n \"procedure\",\n] as const;\n\nfunction normalizeNamespace(namespace: string): string {\n return namespace.trim();\n}\n\nexport function isLikelyUnsafeRegex(pattern: string): boolean {\n const value = pattern.trim();\n if (value.length === 0) return true;\n if (value.length > 120) return true;\n if (/\\\\[1-9]/.test(value)) return true; // backreferences\n if (/\\(\\?<?[=!]/.test(value)) return true; // lookaround assertions\n if (/\\((?:[^()\\\\]|\\\\.)*[+*](?:[^()\\\\]|\\\\.)*\\)[+*{]/.test(value)) return true; // nested quantifiers\n // Conservative fail-closed guardrail: grouped/alternation regexes are user-configurable and can be expensive.\n if (/(^|[^\\\\])[()|]/.test(value)) return true;\n // Multiple quantifiers in one user pattern are high risk for catastrophic backtracking on non-matches.\n const quantifierCount =\n (value.match(/(^|[^\\\\])[*+?]/g)?.length ?? 0) +\n (value.match(/(^|[^\\\\])\\{/g)?.length ?? 0);\n if (quantifierCount > 1) return true;\n return false;\n}\n\nexport function isSafeRouteNamespace(namespace: string): boolean {\n const value = normalizeNamespace(namespace);\n if (value.length === 0) return false;\n if (value === \".\") return false;\n if (value.includes(\"/\") || value.includes(\"\\\\\")) return false;\n if (value.includes(\"..\")) return false;\n return /^[A-Za-z0-9._-]{1,64}$/.test(value);\n}\n\nexport function validateRouteTarget(target: RouteTarget | null | undefined, options?: RoutingEngineOptions): {\n ok: boolean;\n error?: string;\n target?: RouteTarget;\n} {\n if (!target || typeof target !== \"object\") {\n return { ok: false, error: \"target must be an object\" };\n }\n\n const allowedCategories = new Set(options?.allowedCategories ?? DEFAULT_CATEGORIES);\n const allowedNamespaces = options?.allowedNamespaces\n ? new Set(options.allowedNamespaces.map((v) => v.trim()).filter((v) => v.length > 0))\n : null;\n\n const normalized: RouteTarget = {};\n\n if (typeof target.category === \"string\") {\n if (!allowedCategories.has(target.category)) {\n return { ok: false, error: `invalid category: ${target.category}` };\n }\n normalized.category = target.category;\n }\n\n if (typeof target.namespace === \"string\") {\n const namespace = normalizeNamespace(target.namespace);\n if (!isSafeRouteNamespace(namespace)) {\n return { ok: false, error: `invalid namespace: ${target.namespace}` };\n }\n if (allowedNamespaces && !allowedNamespaces.has(namespace)) {\n return { ok: false, error: `namespace not allowed: ${namespace}` };\n }\n normalized.namespace = namespace;\n }\n\n if (!normalized.category && !normalized.namespace) {\n return { ok: false, error: \"target must include category or namespace\" };\n }\n\n return { ok: true, target: normalized };\n}\n\nexport function doesRuleMatch(rule: RouteRule, text: string): boolean {\n if (!rule || typeof rule !== \"object\") return false;\n if (rule.enabled === false) return false;\n if (typeof rule.pattern !== \"string\") return false;\n const pattern = rule.pattern.trim();\n if (pattern.length === 0) return false;\n\n if (rule.patternType === \"keyword\") {\n return text.toLowerCase().includes(pattern.toLowerCase());\n }\n if (rule.patternType !== \"regex\") {\n return false;\n }\n\n if (isLikelyUnsafeRegex(pattern)) {\n return false;\n }\n\n try {\n return new RegExp(pattern, \"i\").test(text);\n } catch {\n return false;\n }\n}\n\nexport function selectRouteRule(text: string, rules: RouteRule[], options?: RoutingEngineOptions): RouteSelection | null {\n const ranked = rules\n .map((rule, index) => ({ rule, index }))\n .sort((a, b) => {\n if (b.rule.priority !== a.rule.priority) return b.rule.priority - a.rule.priority;\n return a.index - b.index;\n });\n\n for (const entry of ranked) {\n if (!doesRuleMatch(entry.rule, text)) continue;\n\n const validation = validateRouteTarget(entry.rule.target, options);\n if (!validation.ok || !validation.target) continue;\n\n return {\n rule: entry.rule,\n target: validation.target,\n };\n }\n\n return null;\n}\n"],"mappings":"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","names":[]}