@romiluz/clawmongo 2026.3.26 → 2026.3.28

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 (507) hide show
  1. package/README.md +84 -49
  2. package/dist/{accounts-boH28BFM.js → accounts-lL2y51Ag.js} +46 -46
  3. package/dist/{acp-cli-DLaTb29R.js → acp-cli-BZvVHRY8.js} +46 -46
  4. package/dist/{action-runtime-Bk-7pvN2.js → action-runtime-DMYRUL4q.js} +10 -10
  5. package/dist/{actions.runtime-Y529miLb.js → actions.runtime-Bd-NMAq6.js} +46 -46
  6. package/dist/{actions.runtime-DVQ4pmcp.js → actions.runtime-gPSeXscW.js} +49 -49
  7. package/dist/{agent-scope-BROpmzKv.js → agent-scope-DXZH506l.js} +1 -1
  8. package/dist/{agents-DZqtbDMD.js → agents-Bt25bmDR.js} +13 -13
  9. package/dist/{agents-BbO-i90j.js → agents-CyJmttnS.js} +114 -114
  10. package/dist/{agents.config-CDS6iAat.js → agents.config-BWm70Hr6.js} +2 -2
  11. package/dist/{agents.config-iY500LY-.js → agents.config-UsCw0kOR.js} +4 -4
  12. package/dist/{audit-Cmj7BNcZ.js → audit-Dg8ZiJrJ.js} +9 -9
  13. package/dist/{audit-DmXeao7s.js → audit-DhXhWoiv.js} +1 -1
  14. package/dist/{audit-channel.collect.runtime-DhP09fjv.js → audit-channel.collect.runtime-CvPUHy1X.js} +2 -2
  15. package/dist/{audit-channel.runtime-C-watgwg.js → audit-channel.runtime-B6ZnOPFc.js} +46 -46
  16. package/dist/{audit-extra.async-B-7dzgcz.js → audit-extra.async-826UZZhJ.js} +3 -3
  17. package/dist/{audit-membership-runtime-CbLi3-5b.js → audit-membership-runtime-DLQrV7Rr.js} +46 -46
  18. package/dist/{audit.deep.runtime-D5VgrTOT.js → audit.deep.runtime-DQDtV7Bc.js} +4 -4
  19. package/dist/{audit.nondeep.runtime-B7M0-7FZ.js → audit.nondeep.runtime-H6B-2xal.js} +4 -4
  20. package/dist/{audit.runtime-BUknqGaP.js → audit.runtime-D2ZRC2A_.js} +47 -47
  21. package/dist/{auth-choice-DfJRosb4.js → auth-choice-CEowrO66.js} +57 -57
  22. package/dist/{auth-choice-CpB99A-L.js → auth-choice-DiufM1b8.js} +55 -55
  23. package/dist/{auth-choice-Bnnngmkx.js → auth-choice-YrGxwB9A.js} +5 -5
  24. package/dist/{auth-choice-options-DvqJHFOp.js → auth-choice-options-n3_uFdT5.js} +2 -2
  25. package/dist/{auth-choice-prompt-DtTjWfPT.js → auth-choice-prompt-DYFzoWa6.js} +50 -50
  26. package/dist/{auth-choice-prompt-Cxz8du6E.js → auth-choice-prompt-sLET2Bkw.js} +1 -1
  27. package/dist/{auth-choice.apply-helpers-Bm5p2ZX7.js → auth-choice.apply-helpers-GU6nZntg.js} +1 -1
  28. package/dist/{auth-choice.plugin-providers.runtime-Dsu6-vb8.js → auth-choice.plugin-providers.runtime-BNqOEEtb.js} +47 -47
  29. package/dist/{auth-profiles-2-OV37OF.js → auth-profiles-BWBQJ6X_.js} +67 -76
  30. package/dist/{auth-profiles.runtime-HcQMBs3K.js → auth-profiles.runtime-DfKRAmQR.js} +46 -46
  31. package/dist/{backend-config-avgzgS5Z.js → backend-config--L236wE2.js} +26 -1
  32. package/dist/{backup-create-B9F0M7-J.js → backup-create-Bll6DgoT.js} +2 -2
  33. package/dist/{base-session-key-DyLtSGkj.js → base-session-key-CA4SoGLF.js} +1 -1
  34. package/dist/{bluebubbles-BTR7u4zE.js → bluebubbles-BsX68JOY.js} +6 -6
  35. package/dist/{browser-cli-tmytvFaa.js → browser-cli-B5euA0cQ.js} +8 -8
  36. package/dist/build-info.json +3 -3
  37. package/dist/bundled/boot-md/handler.js +46 -46
  38. package/dist/bundled/bootstrap-extra-files/handler.js +1 -1
  39. package/dist/bundled/session-memory/handler.js +47 -47
  40. package/dist/{call-Cqem-bCB.js → call-C-_XQxw5.js} +1 -1
  41. package/dist/{call-CxVOiYz-.js → call-lPTaDgAg.js} +6 -6
  42. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  43. package/dist/{channel-Br8MF00M.js → channel-5o-oIU2B.js} +1 -1
  44. package/dist/{channel-BvRm4jSj.js → channel-C1zZg_8b.js} +2 -2
  45. package/dist/{channel-CqkxOhz2.js → channel-CEytBPH-.js} +4 -4
  46. package/dist/{channel-D_h7IfYK.js → channel-Cm65A1lo.js} +7 -7
  47. package/dist/{channel-ngZRDeE3.js → channel-D4K0MVgr.js} +5 -5
  48. package/dist/{channel-account-context-DZhZw4oo.js → channel-account-context-CNZZPDSe.js} +1 -1
  49. package/dist/{channel-plugin-resolution-CXm5HIcm.js → channel-plugin-resolution-WWO690RK.js} +3 -3
  50. package/dist/{channel-reply-pipeline-DdDsf-Lc.js → channel-reply-pipeline-B17-tBLU.js} +1 -1
  51. package/dist/{channel-shared-VIRIADYn.js → channel-shared-RH6YsZ0I.js} +1 -1
  52. package/dist/{channel-summary-BTJxLPN8.js → channel-summary-Cy7WDRjQ.js} +7 -7
  53. package/dist/{channel-summary-DdJtHlvH.js → channel-summary-DV4_b3HZ.js} +2 -2
  54. package/dist/{channel-tFDEkWt9.js → channel-yCiI29Ju.js} +6 -6
  55. package/dist/{channel.runtime-DGnRryi2.js → channel.runtime-C3m1vacV.js} +47 -47
  56. package/dist/{channel.runtime-CdPEA_wb.js → channel.runtime-CUSE7Dn0.js} +47 -47
  57. package/dist/{channel.runtime-0n3_Hz_Y.js → channel.runtime-CtWi36oj.js} +49 -49
  58. package/dist/{channel.runtime-CkHcsWQ3.js → channel.runtime-LUpQZiWg.js} +49 -49
  59. package/dist/{channel.runtime-msXRrVzC.js → channel.runtime-QOkM4mJV.js} +51 -51
  60. package/dist/{channel.runtime-khqV1QRG.js → channel.runtime-rYuUs2po.js} +4 -4
  61. package/dist/{channels-DNza27NY.js → channels-4VTbN2Gt.js} +103 -103
  62. package/dist/{channels-CLZoq3SY.js → channels-BUMnLXLQ.js} +1 -1
  63. package/dist/{channels-cli-Bhsnjsix.js → channels-cli-BYmLj8zw.js} +55 -55
  64. package/dist/{clawbot-cli-9YJNF9pF.js → clawbot-cli-CIYY1u-6.js} +47 -47
  65. package/dist/cli/daemon-cli.js +1 -1
  66. package/dist/{cli-FF5823nM.js → cli-DUA0FvhM.js} +46 -46
  67. package/dist/{command-registry-Dw-TONf0.js → command-registry-B1ECZip_.js} +13 -13
  68. package/dist/{command-registry-TeN0aKPi.js → command-registry-DOAwIs0Y.js} +2 -2
  69. package/dist/{command-secret-gateway-CzHSHmXG.js → command-secret-gateway-Big-n6JY.js} +46 -46
  70. package/dist/{compact.runtime-Bye-pm7Z.js → compact.runtime-BKnPPv9X.js} +46 -46
  71. package/dist/{completion-cli-D08RAGPz.js → completion-cli-BeLNvVTI.js} +3 -3
  72. package/dist/{completion-cli-C0mwyiAb.js → completion-cli-CHwHDPuI.js} +2 -2
  73. package/dist/{config-Ca7pLyBD.js → config-BOWZMmDA.js} +1 -1
  74. package/dist/{config-GKOWhVMv.js → config-C68iwvDj.js} +5 -5
  75. package/dist/{config-cli-CxPspN-S.js → config-cli-BnC336Lu.js} +48 -48
  76. package/dist/{config-guard-BK2hWyPi.js → config-guard-Bn6rZnzK.js} +6 -6
  77. package/dist/{config-validation-DO6o_Kt_.js → config-validation-BBuJZ-WH.js} +2 -2
  78. package/dist/{configure-CODqvxU-.js → configure-CHJDsjOD.js} +120 -120
  79. package/dist/{configure-Dg65gBEw.js → configure-Cctw7tyJ.js} +19 -23
  80. package/dist/{connection-auth-zhL6PVn0.js → connection-auth-C2XaPpF5.js} +1 -1
  81. package/dist/{control-ui-shared-_VwcOcc_.js → control-ui-shared-BC-g150y.js} +1 -1
  82. package/dist/{core-CzwQmKcn.js → core-Cb3XxL6S.js} +1 -1
  83. package/dist/{cron-cli-Dp_EQt2v.js → cron-cli-C10feOtH.js} +7 -7
  84. package/dist/{daemon-cli-Dgpv6Y0R.js → daemon-cli-Ds8mu2VZ.js} +4 -4
  85. package/dist/{daemon-install-Dq1Ix-FO.js → daemon-install-B__sP_7j.js} +49 -49
  86. package/dist/{delegate-BVapk4rY.js → delegate-ByCLviVI.js} +1 -1
  87. package/dist/{deliver-runtime-DPzMjhNU.js → deliver-Co7G5ubS.js} +46 -46
  88. package/dist/{deliver-C32Gg-xU.js → deliver-runtime-2svrtAf1.js} +46 -46
  89. package/dist/{devices-cli-3WN_wB1C.js → devices-cli-CH8nWgcU.js} +6 -6
  90. package/dist/{diagnostic-BbXfhLMi.js → diagnostic-DHTG43d_.js} +1 -1
  91. package/dist/{directory-cli-D_5BYdXm.js → directory-cli-B0REFlKo.js} +48 -48
  92. package/dist/{directory.static-CsajbHw1.js → directory.static-wnw_R8dE.js} +1 -1
  93. package/dist/{discord-C-4y9vOT.js → discord-Cws9MsXn.js} +4 -4
  94. package/dist/{discord-B3mmVXuG.js → discord-b8Ff_BKB.js} +46 -46
  95. package/dist/{dns-cli-CdAnUzRi.js → dns-cli-aRTleL5e.js} +5 -5
  96. package/dist/{doctor-completion-BnqTtLhL.js → doctor-completion-KQWBMnEi.js} +1 -1
  97. package/dist/{doctor-config-preflight-BJ0lGLTO.js → doctor-config-preflight-BDYe5di1.js} +2 -2
  98. package/dist/{doctor-config-preflight-D32oVOWD.js → doctor-config-preflight-Dn5a_Dbr.js} +6 -6
  99. package/dist/{doctor-state-migrations-BklDIib1.js → doctor-state-migrations-BI6HzFyq.js} +47 -47
  100. package/dist/{doctor-state-migrations-Cdk3ep_f.js → doctor-state-migrations-DUPe9zNr.js} +2 -2
  101. package/dist/entry.js +1 -1
  102. package/dist/{exec-approvals-D8OOtgGc.js → exec-approvals-CZz2LqIW.js} +1 -1
  103. package/dist/{exec-approvals-cli-dGISWHE3.js → exec-approvals-cli-KbFpgd-p.js} +9 -9
  104. package/dist/extensionAPI.js +46 -46
  105. package/dist/extensions/amazon-bedrock/index.js +46 -46
  106. package/dist/extensions/anthropic/index.js +46 -46
  107. package/dist/extensions/bluebubbles/index.js +50 -50
  108. package/dist/extensions/bluebubbles/setup-entry.js +48 -48
  109. package/dist/extensions/byteplus/index.js +46 -46
  110. package/dist/extensions/chutes/index.js +48 -48
  111. package/dist/extensions/cloudflare-ai-gateway/index.js +47 -47
  112. package/dist/extensions/device-pair/index.js +46 -46
  113. package/dist/extensions/discord/index.js +48 -48
  114. package/dist/extensions/discord/node_modules/.package-lock.json +3 -3
  115. package/dist/extensions/discord/node_modules/hono/dist/adapter/service-worker/index.js +1 -3
  116. package/dist/extensions/discord/node_modules/hono/dist/cjs/adapter/service-worker/index.js +1 -3
  117. package/dist/extensions/discord/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
  118. package/dist/extensions/discord/node_modules/hono/dist/cjs/middleware/cors/index.js +5 -2
  119. package/dist/extensions/discord/node_modules/hono/dist/cjs/request.js +1 -1
  120. package/dist/extensions/discord/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
  121. package/dist/extensions/discord/node_modules/hono/dist/middleware/cors/index.js +5 -2
  122. package/dist/extensions/discord/node_modules/hono/dist/request.js +1 -1
  123. package/dist/extensions/discord/node_modules/hono/dist/tsconfig.build.tsbuildinfo +1 -1
  124. package/dist/extensions/discord/node_modules/hono/dist/types/client/index.d.ts +1 -1
  125. package/dist/extensions/discord/node_modules/hono/dist/types/client/types.d.ts +20 -0
  126. package/dist/extensions/discord/node_modules/hono/dist/types/request.d.ts +1 -3
  127. package/dist/extensions/discord/node_modules/hono/package.json +1 -1
  128. package/dist/extensions/discord/setup-entry.js +48 -48
  129. package/dist/extensions/elevenlabs/index.js +46 -46
  130. package/dist/extensions/fal/index.js +46 -46
  131. package/dist/extensions/feishu/index.js +55 -55
  132. package/dist/extensions/feishu/setup-entry.js +51 -51
  133. package/dist/extensions/firecrawl/index.js +46 -46
  134. package/dist/extensions/github-copilot/index.js +47 -47
  135. package/dist/extensions/google/index.js +46 -46
  136. package/dist/extensions/huggingface/index.js +47 -47
  137. package/dist/extensions/imessage/index.js +49 -49
  138. package/dist/extensions/imessage/setup-entry.js +49 -49
  139. package/dist/extensions/irc/index.js +49 -49
  140. package/dist/extensions/irc/setup-entry.js +48 -48
  141. package/dist/extensions/kilocode/index.js +47 -47
  142. package/dist/extensions/kimi-coding/index.js +47 -47
  143. package/dist/extensions/line/index.js +9 -9
  144. package/dist/extensions/line/setup-entry.js +8 -8
  145. package/dist/extensions/llm-task/index.js +46 -46
  146. package/dist/extensions/lobster/index.js +5 -5
  147. package/dist/extensions/mattermost/index.js +49 -49
  148. package/dist/extensions/mattermost/setup-entry.js +48 -48
  149. package/dist/extensions/microsoft/index.js +46 -46
  150. package/dist/extensions/minimax/index.js +48 -48
  151. package/dist/extensions/mistral/index.js +47 -47
  152. package/dist/extensions/modelstudio/index.js +47 -47
  153. package/dist/extensions/moonshot/index.js +46 -46
  154. package/dist/extensions/nextcloud-talk/index.js +50 -50
  155. package/dist/extensions/nextcloud-talk/setup-entry.js +49 -49
  156. package/dist/extensions/ollama/index.js +5 -5
  157. package/dist/extensions/openai/index.js +47 -47
  158. package/dist/extensions/opencode/index.js +47 -47
  159. package/dist/extensions/opencode-go/index.js +47 -47
  160. package/dist/extensions/openrouter/index.js +47 -47
  161. package/dist/extensions/openshell/index.js +46 -46
  162. package/dist/extensions/qianfan/index.js +47 -47
  163. package/dist/extensions/qwen-portal-auth/index.js +47 -47
  164. package/dist/extensions/sglang/index.js +46 -46
  165. package/dist/extensions/signal/index.js +49 -49
  166. package/dist/extensions/signal/setup-entry.js +49 -49
  167. package/dist/extensions/slack/index.js +50 -50
  168. package/dist/extensions/slack/setup-entry.js +50 -50
  169. package/dist/extensions/synology-chat/index.js +9 -9
  170. package/dist/extensions/synology-chat/setup-entry.js +8 -8
  171. package/dist/extensions/synthetic/index.js +47 -47
  172. package/dist/extensions/talk-voice/index.js +46 -46
  173. package/dist/extensions/tavily/index.js +46 -46
  174. package/dist/extensions/telegram/index.js +48 -48
  175. package/dist/extensions/telegram/setup-entry.js +48 -48
  176. package/dist/extensions/together/index.js +47 -47
  177. package/dist/extensions/venice/index.js +47 -47
  178. package/dist/extensions/vercel-ai-gateway/index.js +47 -47
  179. package/dist/extensions/vllm/index.js +46 -46
  180. package/dist/extensions/voice-call/index.js +46 -46
  181. package/dist/extensions/volcengine/index.js +46 -46
  182. package/dist/extensions/xai/index.js +46 -46
  183. package/dist/extensions/xiaomi/index.js +47 -47
  184. package/dist/extensions/zai/index.js +47 -47
  185. package/dist/extensions/zalo/index.js +49 -49
  186. package/dist/extensions/zalo/setup-entry.js +48 -48
  187. package/dist/{feishu-C637DYYe.js → feishu-D2fuiOiy.js} +4 -4
  188. package/dist/{gateway-cli-Cuk9d7J2.js → gateway-cli-nOgyXtih.js} +72 -106
  189. package/dist/{gateway-install-token-DlcVm1rP.js → gateway-install-token-nvsTK8KN.js} +4 -4
  190. package/dist/{gateway-rpc-siKa8KpM.js → gateway-rpc-DrH142-v.js} +1 -1
  191. package/dist/{gateway-runtime-roiTaOKO.js → gateway-runtime-CQXKGzrv.js} +2 -2
  192. package/dist/{github-copilot-auth-DJljh3gq.js → github-copilot-auth-C4z2AAd8.js} +3 -3
  193. package/dist/{health-DU_pBiid.js → health-DEgLPyA9.js} +7 -7
  194. package/dist/{health-B1OK1kJg.js → health-H5nbiXvA.js} +48 -48
  195. package/dist/{heartbeat-summary-CMwt9qam.js → heartbeat-summary-CNCptWmA.js} +1 -1
  196. package/dist/{hooks-cli-D42hQEUb.js → hooks-cli-jBhsJaOg.js} +46 -46
  197. package/dist/{identity-file-8MUyIAOy.js → identity-file-CYQnH12I.js} +1 -1
  198. package/dist/{imessage-zqZjecTU.js → imessage-DYqgZpLc.js} +6 -6
  199. package/dist/{imessage-CZb_pS8U.js → imessage-Dau6WdE3.js} +46 -46
  200. package/dist/{inbound-reply-dispatch-B73AkQh4.js → inbound-reply-dispatch-BFE3xy1S.js} +2 -2
  201. package/dist/index.js +2 -2
  202. package/dist/{internal-Bg_k56Pk.js → internal-DLE9baj7.js} +0 -24
  203. package/dist/{io-DE9vm7Eo.js → io-Du0b8gMO.js} +2 -2
  204. package/dist/{io-B7rO2wud.js → io-dJgqp8U8.js} +4 -4
  205. package/dist/{irc-BWzsfr2V.js → irc-BRaOVUse.js} +2 -2
  206. package/dist/{kb-cli-BOPGkNfJ.js → kb-cli-Cdif_vwn.js} +12 -12
  207. package/dist/{library-i-2ymInt.js → library-BwjFIWw3.js} +46 -46
  208. package/dist/{lifecycle-core-DwIo1PfK.js → lifecycle-core-DNO4MItg.js} +1 -1
  209. package/dist/line/send.js +6 -6
  210. package/dist/{line-DbTKdVgY.js → line-BCXUGrVz.js} +2 -2
  211. package/dist/{llm-slug-generator-Dm30OM2W.js → llm-slug-generator-B55FZ1aG.js} +3 -3
  212. package/dist/llm-slug-generator.js +47 -47
  213. package/dist/{logging-BM4mQ53W.js → logging-BvOzg0cM.js} +1 -1
  214. package/dist/{logging-0tvlVvFG.js → logging-nWyKsj9d.js} +5 -5
  215. package/dist/{login-qr-DQPSabxI.js → login-qr-C0QA3j4x.js} +46 -46
  216. package/dist/{logs-cli-ZnHk5eku.js → logs-cli-thlXBA9n.js} +7 -7
  217. package/dist/{manager.runtime-D3vjUOZF.js → manager.runtime-SoTq-tT4.js} +46 -46
  218. package/dist/{matrix-migration-snapshot-CRKiHq6Y.js → matrix-migration-snapshot-_6Rg-iLO.js} +2 -2
  219. package/dist/{mattermost-Bqn7Fd5U.js → mattermost-2nv5O_jQ.js} +2 -2
  220. package/dist/{mcp-cli-7aN2vJv-.js → mcp-cli-1vpy_yti.js} +5 -5
  221. package/dist/{mcp-config-NVrqojpu.js → mcp-config-Bmi2GUum.js} +1 -1
  222. package/dist/{media-understanding.runtime-DesF8Xhs.js → media-understanding.runtime-Wh-_SFK_.js} +46 -46
  223. package/dist/{memory-cli-CWqIJQS5.js → memory-cli-COJRHkaJ.js} +46 -46
  224. package/dist/{memory-search-DyxoUpq2.js → memory-search-CGmdrdM1.js} +1 -1
  225. package/dist/{memory-search-CgoWYj0V.js → memory-search-Cy36nO15.js} +3 -3
  226. package/dist/{model-picker-DX9P5pDr.js → model-picker-CYWvoS3z.js} +48 -48
  227. package/dist/{model-picker-Ds7-VqDS.js → model-picker-_32ihKqK.js} +4 -4
  228. package/dist/{model-picker.runtime-DqDt4s3S.js → model-picker.runtime-DBT5uEFi.js} +49 -49
  229. package/dist/{model-selection-DXFVauys.js → model-selection-014eeYCV.js} +1 -1
  230. package/dist/{model-suppression.runtime-8mU0VJs6.js → model-suppression.runtime-GTI9Rm85.js} +46 -46
  231. package/dist/{models-GXQSWyBX.js → models-Be9EWpVm.js} +54 -54
  232. package/dist/{models-CVG-VMBa.js → models-CX35daXC.js} +14 -14
  233. package/dist/{models-cli-Cvy8rGqU.js → models-cli-BYjac3oq.js} +54 -54
  234. package/dist/{models-config-BdanqM9X.js → models-config-Agv-ThDH.js} +46 -46
  235. package/dist/{models-config.providers.discovery-BHZ3WglC.js → models-config.providers.discovery-BJwjDHsg.js} +1 -1
  236. package/dist/{mongodb-analytics-BszyEhsq.js → mongodb-analytics-HJKYeseb.js} +2 -2
  237. package/dist/{mongodb-analytics-CcSYo_ae.js → mongodb-analytics-mnKJih5x.js} +1 -1
  238. package/dist/{mongodb-auto-setup-QcwgZSN9.js → mongodb-auto-setup-CCElSwNy.js} +2 -2
  239. package/dist/{mongodb-kb-C-VmGOq7.js → mongodb-kb-1tSOXXb9.js} +3 -3
  240. package/dist/{mongodb-kb-BotgVda9.js → mongodb-kb-CdSvNe3w.js} +2 -2
  241. package/dist/{mongodb-kb-search-CoIAFX8n.js → mongodb-kb-search-Dq6E746K.js} +1 -1
  242. package/dist/{mongodb-kb-search-BBYY_d_r.js → mongodb-kb-search-DvsXIUy6.js} +3 -3
  243. package/dist/{mongodb-manager-BVfTfpHf.js → mongodb-manager-DEZIQXuo.js} +10 -10
  244. package/dist/{mongodb-manager-BJ0PAYF_.js → mongodb-manager-NkerSpvH.js} +1183 -331
  245. package/dist/{mongodb-procedures-DNPmmW5r.js → mongodb-procedures-DI-_Dakz.js} +7 -3
  246. package/dist/{mongodb-procedures-D3M2Ph8E.js → mongodb-procedures-tjhGdBV7.js} +3 -3
  247. package/dist/{mongodb-schema-JpDXcAUV.js → mongodb-schema-DN3aspLa.js} +1 -1
  248. package/dist/{mongodb-schema-BI4Ze_ZV.js → mongodb-schema-Dt6jxcPL.js} +298 -4
  249. package/dist/{mongodb-search-VFKd72IZ.js → mongodb-search-DMsUyfpa.js} +2 -2
  250. package/dist/{mongodb-structured-memory-DnwUJ6SA.js → mongodb-structured-memory-D-3SEfTu.js} +58 -2
  251. package/dist/{mongodb-structured-memory-BySGexcm.js → mongodb-structured-memory-lpyyW0kn.js} +3 -3
  252. package/dist/{monitor-DGE0bx3s.js → monitor-BZFy1RTb.js} +47 -47
  253. package/dist/{monitor-Dfc0KXMD.js → monitor-DPYGxeY_.js} +5 -5
  254. package/dist/{monitor-CZZlkQUU.js → monitor-Duykki-j.js} +51 -51
  255. package/dist/{monitor-B61bVnMW.js → monitor-gq31SALd.js} +8 -8
  256. package/dist/{nextcloud-talk-CnwOv1rG.js → nextcloud-talk-C_-LfGeq.js} +2 -2
  257. package/dist/{node-cli-Avub0RKe.js → node-cli-NpJzvfQW.js} +12 -12
  258. package/dist/{nodes-cli-qSE-cmgX.js → nodes-cli-O5HciXeP.js} +10 -10
  259. package/dist/{nodes-screen-DQw8F5rA.js → nodes-screen-BIwiB35h.js} +1 -1
  260. package/dist/{oauth.runtime-825pMCgB.js → oauth.runtime-BxjW8DFO.js} +46 -46
  261. package/dist/{oauth.runtime-BCwH9-Yl.js → oauth.runtime-DKU2STuA.js} +46 -46
  262. package/dist/{oauth.runtime-BSddaUzc.js → oauth.runtime-mFizWM72.js} +46 -46
  263. package/dist/{onboard-CUbnVxXL.js → onboard-B6H0qDtg.js} +1 -1
  264. package/dist/{onboard-BwC0LbCx.js → onboard-C1AmXQ6f.js} +8 -8
  265. package/dist/{onboard-Cw65XmEU.js → onboard-DPdj0IBu.js} +2 -2
  266. package/dist/{onboard-channels-BYNDTtRI.js → onboard-channels-Cmj_5qXQ.js} +24 -24
  267. package/dist/{onboard-channels-CIR1ZSii.js → onboard-channels-Wf3nY9Bf.js} +97 -97
  268. package/dist/{onboard-custom-FImARgQC.js → onboard-custom-DILgXkiq.js} +50 -50
  269. package/dist/{onboard-custom-C4qOVxtG.js → onboard-custom-DlDCjvIw.js} +4 -4
  270. package/dist/{onboard-helpers-DW9Mskds.js → onboard-helpers-CqpD9TVU.js} +48 -48
  271. package/dist/{onboard-helpers-D3xV_T96.js → onboard-helpers-D-PLdtHT.js} +3 -3
  272. package/dist/{onboard-hooks-B0gJVtBY.js → onboard-hooks-MQ8QOguv.js} +2 -2
  273. package/dist/{onboard-remote-BMLo6WKH.js → onboard-remote-BZKWgKVw.js} +50 -50
  274. package/dist/{onboard-remote-XUah3N3G.js → onboard-remote-Bnad5LMv.js} +2 -2
  275. package/dist/{onboard-search-DHCzqxgq.js → onboard-search-Dyv1IuQ4.js} +46 -46
  276. package/dist/{onboard-skills-LXCIpyir.js → onboard-skills-DdCu1_hE.js} +1 -1
  277. package/dist/{onboard-skills-CH6q90Pf.js → onboard-skills-W_252asS.js} +49 -49
  278. package/dist/{onboarding-memory-BWEsBe08.js → onboarding-memory-BRHSmwx3.js} +24 -15
  279. package/dist/{outbound-media-CqfP0r4a.js → outbound-media-CHc08Sj8.js} +1 -1
  280. package/dist/{pairing-cli-BdCkQG2S.js → pairing-cli-oNWkjwCt.js} +5 -5
  281. package/dist/{persistent-dedupe-DNnh7hrR.js → persistent-dedupe-CS_uyVoq.js} +1 -1
  282. package/dist/{pi-model-discovery-runtime-DyT9C3Ap.js → pi-model-discovery-runtime-BJVREOXf.js} +46 -46
  283. package/dist/{pi-tools.before-tool-call.runtime-CA2js1Ig.js → pi-tools.before-tool-call.runtime-w-Q4HA_S.js} +6 -6
  284. package/dist/{plugin-install-DgvJfz7X.js → plugin-install-BysMw7Sl.js} +47 -47
  285. package/dist/{plugin-install-BKuy_--2.js → plugin-install-EyES0vGP.js} +2 -2
  286. package/dist/{plugin-registry-D-6OBqUU.js → plugin-registry-BenF9SYR.js} +47 -47
  287. package/dist/{plugin-registry-Dsx_6z3N.js → plugin-registry-CRV_Bc8K.js} +3 -3
  288. package/dist/plugin-sdk/account-resolution.js +46 -46
  289. package/dist/plugin-sdk/acp-runtime.js +46 -46
  290. package/dist/plugin-sdk/agent-runtime.js +46 -46
  291. package/dist/plugin-sdk/channel-inbound.js +46 -46
  292. package/dist/plugin-sdk/channel-reply-pipeline.js +3 -3
  293. package/dist/plugin-sdk/channel-runtime.js +46 -46
  294. package/dist/plugin-sdk/channel-setup.js +1 -1
  295. package/dist/plugin-sdk/command-auth.js +46 -46
  296. package/dist/plugin-sdk/compat.js +5 -5
  297. package/dist/plugin-sdk/config-runtime.js +46 -46
  298. package/dist/plugin-sdk/conversation-runtime.js +46 -46
  299. package/dist/plugin-sdk/core.js +5 -5
  300. package/dist/plugin-sdk/directory-runtime.js +1 -1
  301. package/dist/plugin-sdk/discord.js +46 -46
  302. package/dist/plugin-sdk/gateway-runtime.js +8 -8
  303. package/dist/plugin-sdk/image-generation.js +46 -46
  304. package/dist/plugin-sdk/index.js +46 -46
  305. package/dist/plugin-sdk/infra-runtime.js +46 -46
  306. package/dist/plugin-sdk/llm-task.js +46 -46
  307. package/dist/plugin-sdk/matrix-runtime-heavy.js +50 -50
  308. package/dist/plugin-sdk/media-runtime.js +46 -46
  309. package/dist/plugin-sdk/media-understanding-runtime.js +46 -46
  310. package/dist/plugin-sdk/media-understanding.js +46 -46
  311. package/dist/plugin-sdk/ollama-setup.js +8 -8
  312. package/dist/plugin-sdk/plugin-runtime.js +46 -46
  313. package/dist/plugin-sdk/provider-auth-api-key.js +46 -46
  314. package/dist/plugin-sdk/provider-auth-login.js +1 -1
  315. package/dist/plugin-sdk/provider-auth.js +46 -46
  316. package/dist/plugin-sdk/provider-models.js +5 -5
  317. package/dist/plugin-sdk/provider-onboard.js +5 -5
  318. package/dist/plugin-sdk/provider-setup.js +49 -49
  319. package/dist/plugin-sdk/provider-stream.js +46 -46
  320. package/dist/plugin-sdk/provider-usage.js +4 -4
  321. package/dist/plugin-sdk/reply-history.js +3 -3
  322. package/dist/plugin-sdk/reply-runtime.js +46 -46
  323. package/dist/plugin-sdk/routing.js +3 -3
  324. package/dist/plugin-sdk/sandbox.js +46 -46
  325. package/dist/plugin-sdk/self-hosted-provider-setup.js +48 -48
  326. package/dist/plugin-sdk/setup-runtime.js +1 -1
  327. package/dist/plugin-sdk/setup.js +1 -1
  328. package/dist/plugin-sdk/speech-runtime.js +46 -46
  329. package/dist/plugin-sdk/speech.js +46 -46
  330. package/dist/plugin-sdk/src/agents/workspace.d.ts +1 -3
  331. package/dist/plugin-sdk/src/config/types.memory.d.ts +44 -0
  332. package/dist/plugin-sdk/src/memory/backend-config.d.ts +24 -0
  333. package/dist/plugin-sdk/src/memory/index.d.ts +12 -4
  334. package/dist/plugin-sdk/src/memory/mongodb-entity-extractor.d.ts +33 -0
  335. package/dist/plugin-sdk/src/memory/mongodb-episodes.d.ts +16 -0
  336. package/dist/plugin-sdk/src/memory/mongodb-events.d.ts +9 -0
  337. package/dist/plugin-sdk/src/memory/mongodb-graph.d.ts +30 -3
  338. package/dist/plugin-sdk/src/memory/mongodb-manager.d.ts +18 -0
  339. package/dist/plugin-sdk/src/memory/mongodb-mutations.d.ts +38 -0
  340. package/dist/plugin-sdk/src/memory/mongodb-procedures.d.ts +32 -0
  341. package/dist/plugin-sdk/src/memory/mongodb-profile.d.ts +71 -0
  342. package/dist/plugin-sdk/src/memory/mongodb-query-cache.d.ts +68 -0
  343. package/dist/plugin-sdk/src/memory/mongodb-query-rewriter.d.ts +39 -0
  344. package/dist/plugin-sdk/src/memory/mongodb-reranker.d.ts +32 -0
  345. package/dist/plugin-sdk/src/memory/mongodb-schema.d.ts +3 -0
  346. package/dist/plugin-sdk/src/memory/mongodb-telemetry.d.ts +69 -0
  347. package/dist/plugin-sdk/text-runtime.js +6 -6
  348. package/dist/plugin-sdk/web-media.js +3 -3
  349. package/dist/plugin-sdk/zalo.js +47 -47
  350. package/dist/plugin-sdk/zalouser.js +47 -47
  351. package/dist/plugins/build-smoke-entry.js +46 -46
  352. package/dist/plugins/runtime/index.js +46 -46
  353. package/dist/{plugins-cli-C6wGAkD9.js → plugins-cli-BUiP4x7l.js} +46 -46
  354. package/dist/{policy-CcgojW9R.js → policy-DnUfJkOZ.js} +1 -1
  355. package/dist/{preflight-audio.runtime-Cyz9Zu89.js → preflight-audio.runtime-D3_iaSgF.js} +46 -46
  356. package/dist/{probe-auth-BmluVNJZ.js → probe-auth-BbNdYwb0.js} +1 -1
  357. package/dist/{probe-auth-DrgTJ7ki.js → probe-auth-CB9y2dLl.js} +7 -7
  358. package/dist/{program-CHFcfOlC.js → program-uHYlUP3c.js} +4 -4
  359. package/dist/{prompt-select-styled-Ck38XMb3.js → prompt-select-styled-DoTAWghe.js} +25 -51
  360. package/dist/{provider-api-key-auth.runtime-AT16DTa8.js → provider-api-key-auth.runtime-B3H0dODg.js} +46 -46
  361. package/dist/{provider-auth-choice-UhIkLc6q.js → provider-auth-choice-HRfxXEHk.js} +6 -6
  362. package/dist/{provider-auth-choice-helpers-CXWmWOdR.js → provider-auth-choice-helpers-2jZnBKMm.js} +1 -1
  363. package/dist/{provider-auth-choice-preference-TgulgKlz.js → provider-auth-choice-preference-CqKryjBB.js} +6 -6
  364. package/dist/{provider-auth-choice.runtime-FTNgi8Yh.js → provider-auth-choice.runtime-BaFSZgQG.js} +48 -48
  365. package/dist/{provider-auth-choice.runtime-CP91b3vK.js → provider-auth-choice.runtime-DPHuj1_l.js} +2 -2
  366. package/dist/{provider-auth-choices-BfWvatIg.js → provider-auth-choices-CqFh00uK.js} +1 -1
  367. package/dist/{provider-auth-guidance-D4-q7IHl.js → provider-auth-guidance-DmdBoDfS.js} +2 -2
  368. package/dist/{provider-auth-input-DnQ-RiX5.js → provider-auth-input-FZYEJh19.js} +46 -46
  369. package/dist/{provider-auth-login-D7eLUZwy.js → provider-auth-login-B-XedaK5.js} +1 -1
  370. package/dist/{provider-auth-login.runtime-BG_qqxZk.js → provider-auth-login.runtime-f9dxfJUB.js} +49 -49
  371. package/dist/{provider-model-allowlist-CC0lIQ6w.js → provider-model-allowlist-C16pn0B8.js} +1 -1
  372. package/dist/{provider-models-DbK6xrje.js → provider-models-PaymKOme.js} +1 -1
  373. package/dist/{provider-ollama-setup-B4RWr9oj.js → provider-ollama-setup-k5ozCUi2.js} +3 -3
  374. package/dist/{provider-onboarding-config-W5sF0oD8.js → provider-onboarding-config-qCltsaVl.js} +1 -1
  375. package/dist/{provider-runtime.runtime-Cva8S4wx.js → provider-runtime.runtime-CzVe0WBb.js} +46 -46
  376. package/dist/{provider-self-hosted-setup-jAzqLaqv.js → provider-self-hosted-setup-zxYnIftX.js} +3 -3
  377. package/dist/{provider-usage-CEgSCMW4.js → provider-usage-C9KdAhuS.js} +46 -46
  378. package/dist/{provider-usage-CCIC3SdY.js → provider-usage-DexJNI_0.js} +1 -1
  379. package/dist/{provider-wizard-DQd5eYhX.js → provider-wizard-D4RbMR2D.js} +2 -2
  380. package/dist/{push-apns-DQN5pcl6.js → push-apns-BAc0-Jy5.js} +1 -1
  381. package/dist/{pw-ai-BiXz8un2.js → pw-ai-C8v0s5wH.js} +6 -6
  382. package/dist/{qr-cli-B8bBpCd2.js → qr-cli-BpqLcmYC.js} +47 -47
  383. package/dist/{qr-cli-DOuhqzho.js → qr-cli-D0zqiQMl.js} +4 -4
  384. package/dist/{reactions-BkyHqIw4.js → reactions-CjJbniYK.js} +1 -1
  385. package/dist/{read-only-account-inspect-Cfaj7PFb.js → read-only-account-inspect-CEJ1r7AW.js} +3 -3
  386. package/dist/{read-only-account-inspect.discord.runtime-kreMwVgq.js → read-only-account-inspect.discord.runtime-C1n8r_Kj.js} +46 -46
  387. package/dist/{read-only-account-inspect.slack.runtime-DgV5VZ-n.js → read-only-account-inspect.slack.runtime-DAOzA9ke.js} +46 -46
  388. package/dist/{read-only-account-inspect.telegram.runtime-BQaHHCIS.js → read-only-account-inspect.telegram.runtime-CfNlnogC.js} +46 -46
  389. package/dist/{redact-snapshot-PisBVQFW.js → redact-snapshot-qQFn3bz8.js} +3 -3
  390. package/dist/{register.agent-CXTssAWM.js → register.agent-DC5QbIE7.js} +114 -114
  391. package/dist/{register.backup-MRTb86c6.js → register.backup-BRxspFkM.js} +6 -6
  392. package/dist/{register.configure-BfE3p-3h.js → register.configure-B7zhRBla.js} +120 -120
  393. package/dist/{register.maintenance-D_Gn-ZDc.js → register.maintenance-CCmppLW1.js} +65 -65
  394. package/dist/{register.message-s1z2QSP2.js → register.message-DSBPJS4x.js} +47 -47
  395. package/dist/{register.onboard-Cd-OV7xm.js → register.onboard-C4D9pjf7.js} +54 -54
  396. package/dist/{register.setup-DclQVR9m.js → register.setup-C4pDa0HW.js} +52 -52
  397. package/dist/{register.status-health-sessions-D-Xp8ae7.js → register.status-health-sessions-ClxLTjC5.js} +55 -55
  398. package/dist/{register.subclis-pcAQ13jU.js → register.subclis-BauDruMA.js} +30 -30
  399. package/dist/{register.subclis-BCvQmGkr.js → register.subclis-WyYRaoa-.js} +1 -1
  400. package/dist/{replies-DQwDaTBP.js → replies-CZGcXYVE.js} +1 -1
  401. package/dist/{reply-history-DVLrt4Es.js → reply-history-1yT9Tzib.js} +1 -1
  402. package/dist/{routes-CBWjQBhD.js → routes-D8CYDLDF.js} +5 -5
  403. package/dist/{rpc-O719GSVf.js → rpc-D8I_Qzen.js} +1 -1
  404. package/dist/{run-main-C_W2kjf-.js → run-main-BwEbDjI-.js} +19 -19
  405. package/dist/{runtime-COpSaRtb.js → runtime-CmSMHqwN.js} +1 -1
  406. package/dist/{runtime-PbP8BVEV.js → runtime-DQaeo-1L.js} +2 -2
  407. package/dist/{runtime-discord-ops.runtime-CmStqYK4.js → runtime-discord-ops.runtime-8w-055sR.js} +46 -46
  408. package/dist/{runtime-slack-ops.runtime-Cm1935hR.js → runtime-slack-ops.runtime-XJJrByCY.js} +48 -48
  409. package/dist/{runtime-telegram-ops.runtime-CKozoVxf.js → runtime-telegram-ops.runtime-wOdrd2eH.js} +46 -46
  410. package/dist/{sandbox-cli-BIyJ-1r-.js → sandbox-cli-CvFmY6Kq.js} +46 -46
  411. package/dist/{search-manager-BVE1EPHv.js → search-manager-ZNiamJHa.js} +6 -6
  412. package/dist/{search-manager-DMTYqpmg.js → search-manager-zaZ4tAYz.js} +5 -5
  413. package/dist/{secrets-cli-CMMtWzst.js → secrets-cli-D5a_lvAP.js} +47 -47
  414. package/dist/{security-cli-Bw4cVkTN.js → security-cli-DJovxmST.js} +47 -47
  415. package/dist/{send-CfI8y11o.js → send-C3KhjjcU.js} +1 -1
  416. package/dist/{send-C8HDmafP.js → send-CIkS5fLj.js} +2 -2
  417. package/dist/{server-0n2tu0ff.js → server-B1z10Ohi.js} +6 -6
  418. package/dist/{server-node-events-J5-mGOea.js → server-node-events-D3_b2nU-.js} +47 -47
  419. package/dist/{server-startup-matrix-migration-CMBUtdN2.js → server-startup-matrix-migration-DDRaKUPQ.js} +3 -3
  420. package/dist/{session-cost-usage-CrPCO4HN.js → session-cost-usage-BwIud0lY.js} +46 -46
  421. package/dist/{sessions-n_Z6bcbr.js → sessions-B5Pffwj6.js} +3 -3
  422. package/dist/{sessions-BK_M3Nu1.js → sessions-ClamZkvP.js} +47 -47
  423. package/dist/{setup-OCrVlmv7.js → setup-B8gsbmH4.js} +18 -18
  424. package/dist/{setup-core-BVBCTInv.js → setup-core-B6csKf5s.js} +2 -2
  425. package/dist/{setup-core-z8Q1sgUU.js → setup-core-DkgiVKzw.js} +2 -2
  426. package/dist/{setup-entry-CvuaW-4I.js → setup-entry-C8XH3da9.js} +2 -2
  427. package/dist/{setup-entry-Jf6V23s6.js → setup-entry-CMSlnfft.js} +3 -3
  428. package/dist/{setup-entry-Bo3chgoG.js → setup-entry-CZVAwPKZ.js} +2 -2
  429. package/dist/{setup-entry-Co-YP41_.js → setup-entry-Duh-ewBV.js} +3 -3
  430. package/dist/{setup-entry-BnSZlMP1.js → setup-entry-ksUWY45r.js} +2 -2
  431. package/dist/{setup-entry-BNSYJMzp.js → setup-entry-vQgAuveW.js} +2 -2
  432. package/dist/{setup-group-access-BYV3O8yu.js → setup-group-access-CTlnq-M9.js} +1 -1
  433. package/dist/{setup-surface-B6XBqyMJ.js → setup-surface-B7uYEI9F.js} +2 -2
  434. package/dist/{setup-surface-fixjWejm.js → setup-surface-CMgQr2R9.js} +5 -5
  435. package/dist/{setup-surface-CzzV3QV6.js → setup-surface-Yd-YLGfa.js} +46 -46
  436. package/dist/{setup-wizard-proxy-DFDQV7FN.js → setup-wizard-proxy-CHGAY6ob.js} +1 -1
  437. package/dist/{setup.finalize-WT9kXSLX.js → setup.finalize-C2bq4D8j.js} +58 -58
  438. package/dist/{setup.gateway-config-Bp50kjo3.js → setup.gateway-config-BGgVOvQf.js} +48 -48
  439. package/dist/{shared-CyR3Ki--.js → shared-BEMZg0vb.js} +5 -5
  440. package/dist/{shared-DXzPv5D7.js → shared-BYRyVoVx.js} +5 -5
  441. package/dist/{shared-DCOVJ3QB.js → shared-Bj3fwdyM.js} +4 -4
  442. package/dist/{shared-B8_JHpU2.js → shared-CSydqOgE.js} +4 -4
  443. package/dist/{shared-C3fKAUbw.js → shared-DLAg-pKT.js} +3 -3
  444. package/dist/{signal-D16eMrBf.js → signal-Dh6z2uaT.js} +5 -5
  445. package/dist/{signal-oGrspg1k.js → signal-FEtxekyc.js} +46 -46
  446. package/dist/{skills-cli-CY6lUTRv.js → skills-cli-9NuRJd3Z.js} +5 -5
  447. package/dist/{slack-ueYeeNF7.js → slack-Ci1VArkq.js} +48 -48
  448. package/dist/{slack-B1GgT1_u.js → slack-CjslLjTc.js} +5 -5
  449. package/dist/{slash-commands.runtime-1q-llUpe.js → slash-commands.runtime-COXzcGjL.js} +46 -46
  450. package/dist/{slash-dispatch.runtime-BqJ1FZZ6.js → slash-dispatch.runtime-D5j8d7dg.js} +47 -47
  451. package/dist/{slash-skill-commands.runtime-D-BEZgQ1.js → slash-skill-commands.runtime-6U65Nany.js} +46 -46
  452. package/dist/{status-CnKcjD2h.js → status-BWUft8B5.js} +16 -16
  453. package/dist/{status-C1BR9Hft.js → status-BjV1ysoW.js} +50 -50
  454. package/dist/{status-D_1nxvoi.js → status-CM77XYRR.js} +4 -4
  455. package/dist/{status-Dp3OriYl.js → status-D7XHAzLz.js} +46 -46
  456. package/dist/{status-DoSH4nEL.js → status-DwO4xEHI.js} +54 -54
  457. package/dist/{status-json-DwNPzoCk.js → status-json-BYDBfkr3.js} +19 -19
  458. package/dist/{status-B45v-A8b.js → status-yoA_KX2O.js} +1 -1
  459. package/dist/{status.link-channel-Cz8GoHZ2.js → status.link-channel-DkISMfW8.js} +2 -2
  460. package/dist/{status.scan.deps.runtime-BQGei2B_.js → status.scan.deps.runtime-B6__B0kL.js} +14 -14
  461. package/dist/{status.scan.runtime-D4HkKTZu.js → status.scan.runtime-BAkcX3vO.js} +2 -2
  462. package/dist/{status.summary-Dxo5qDuD.js → status.summary-DNaMhaXy.js} +8 -8
  463. package/dist/{subagent-orphan-recovery-BPa7yoId.js → subagent-orphan-recovery-DtK8inah.js} +46 -46
  464. package/dist/{subagent-registry-runtime-B6homy_H.js → subagent-registry-runtime-02s7QJo3.js} +46 -46
  465. package/dist/{synology-chat-DY8xNv_g.js → synology-chat-QURTpvMf.js} +2 -2
  466. package/dist/{system-cli-CkWRbLu4.js → system-cli-BXd7evEt.js} +7 -7
  467. package/dist/{system-run-command-jY6Is_ri.js → system-run-command-CQCx0f24.js} +1 -1
  468. package/dist/telegram/audit.js +1 -1
  469. package/dist/telegram/token.js +46 -46
  470. package/dist/{telegram-uQdpyLeS.js → telegram-Btwvg0PX.js} +46 -46
  471. package/dist/{telegram-Bnigf1Qe.js → telegram-Dh5gM1mc.js} +7 -7
  472. package/dist/{tool-policy-match-BLASiL8y.js → tool-policy-match-B6J0bSfQ.js} +1 -1
  473. package/dist/{tui-Dj52JiFV.js → tui-CKGcNyM8.js} +6 -6
  474. package/dist/{tui-cli-B4SN4wzX.js → tui-cli-D3CLnnB9.js} +47 -47
  475. package/dist/{update-cli-CEAEBCp2.js → update-cli-DQ4j_nIh.js} +69 -69
  476. package/dist/{update-offset-store-Bp1RjZK2.js → update-offset-store-RxVdgbyo.js} +46 -46
  477. package/dist/{upsert-with-lock-CFIy4b7I.js → upsert-with-lock-BqkAnFym.js} +1 -1
  478. package/dist/{web-media-BJ-azd7j.js → web-media-BM1Mg6AN.js} +1 -1
  479. package/dist/{webhook-shared-DYKTXPVw.js → webhook-shared-UDKLpQnU.js} +1 -1
  480. package/dist/{webhooks-cli-CEBJbLqS.js → webhooks-cli-Ca3PlK8h.js} +5 -5
  481. package/dist/{whatsapp-63jqHVrE.js → whatsapp-CHEvDa2g.js} +46 -46
  482. package/dist/{with-timeout-CvaBvNie.js → with-timeout-CvBH67nj.js} +2 -2
  483. package/dist/{workspace-DuH1agxz.js → workspace-uCYzunu4.js} +5 -33
  484. package/dist/{zalo-CTrI2C4i.js → zalo-Dr4ysJLW.js} +1 -1
  485. package/dist/{zalo-Sw_XHo3-.js → zalo-keqX1Wnx.js} +2 -2
  486. package/docs/concepts/agent-workspace.md +0 -5
  487. package/docs/concepts/memory.md +6 -12
  488. package/docs/plans/2026-03-22-semantic-cache-telemetry-docs-plan.md +1431 -0
  489. package/docs/plans/2026-03-22-supermemory-steals-plan.md +1679 -0
  490. package/docs/plans/2026-03-23-almost-perfect-sprint-plan.md +1080 -0
  491. package/docs/plans/2026-03-23-master-steal-list.md +224 -0
  492. package/docs/plans/2026-03-23-memory-md-deprecation-plan.md +632 -0
  493. package/docs/plans/2026-03-23-production-readiness-e2e-plan.md +659 -0
  494. package/docs/plans/2026-03-23-supermemory-audit-fixes-plan.md +1291 -0
  495. package/docs/reference/clawmongo-vs-default-memory.md +2 -2
  496. package/docs/reference/heart-brain-boundary.md +8 -10
  497. package/docs/reference/memory-config.md +3 -4
  498. package/docs/reference/mongodb-capabilities.md +246 -9
  499. package/docs/reference/templates/AGENTS.md +5 -10
  500. package/docs/research/2026-03-22-atlas-local-preview-web.md +41 -31
  501. package/docs/research/2026-03-23-agent-management-ui-github.md +482 -0
  502. package/docs/research/2026-03-23-almost-perfect-mongodb-docs.md +255 -0
  503. package/docs/research/2026-03-23-company-os-agent-ui-web.md +511 -0
  504. package/docs/research/2026-03-23-supermemory-audit-fixes-mongodb-research.md +995 -0
  505. package/docs/start/clawmongo-getting-started.md +1 -1
  506. package/package.json +1 -1
  507. /package/dist/{memory-BAVM2Jxh.js → memory-CcbELE82.js} +0 -0
@@ -0,0 +1,1291 @@
1
+ # SuperMemory Audit Fixes Implementation Plan
2
+
3
+ > **For Claude:** REQUIRED: Follow this plan task-by-task using TDD.
4
+ > **Audit Source:** Two audit agents found 12 dead code issues (3 HIGH) and 19 improvement findings (3 CRITICAL, 5 HIGH, 6 MEDIUM).
5
+ > **Research:** See `docs/research/2026-03-23-supermemory-audit-fixes-mongodb-research.md` for MongoDB documentation research.
6
+
7
+ **Goal:** Fix all CRITICAL + HIGH issues from the supermemory audit, plus quick-win MEDIUMs. 15 fixes total across 9 files.
8
+
9
+ **Architecture:** Surgical fixes to existing modules. No new collections, no new files (except tests). Manual RRF for score normalization. `bulkWrite` for N+1 entity upserts. `$percentile` for server-side latency stats.
10
+
11
+ **Tech Stack:** TypeScript ESM, MongoDB latest (atlas-local:preview — always latest version, currently 8.2+), Vitest
12
+
13
+ **MongoDB Version Policy:** ClawMongo targets ONLY `mongodb-atlas-local:preview` which always ships the latest MongoDB. No version fallbacks, no backward compatibility concerns, no feature-gating by version. Use the most innovative features available.
14
+
15
+ **Prerequisites:** All existing tests pass. `pnpm test -- src/memory` green baseline.
16
+
17
+ ---
18
+
19
+ ## Plan: SuperMemory Audit Fixes
20
+
21
+ ### Request Summary
22
+
23
+ - Fix 15 audit findings (3 CRITICAL, 5 HIGH, 7 MEDIUM quick-wins) to harden the supermemory subsystem.
24
+
25
+ ### Requirements Snapshot
26
+
27
+ - C1: Add `AbortSignal.timeout(10_000)` to Voyage rerank API fetch
28
+ - C2: Add `synthesizeProfile()` method to manager; split `$or` in `$lookup` to two indexed `$eq` lookups
29
+ - C3: Implement manual RRF in `searchV2` to normalize scores across paths
30
+ - H1: Replace sequential entity/relation upserts with `bulkWrite({ ordered: false })`
31
+ - H2: Remove `LLMEntityExtractor` config false bridge; add explicit log warning for `graph.entityExtraction` config
32
+ - H3: Throw validation error for "llm"/"hyde" query rewrite methods instead of silent fallback
33
+ - H4: Derive cache TTL from `pathsExecuted` (per-document TTL) instead of static config
34
+ - H5: Filter empty snippets before sending to reranker
35
+ - H6: Entity-extraction telemetry: add `emitTelemetry` to `extractAndUpsertEntities`
36
+ - H7: Clean up aggressive synonym expansions, add max expansion ratio
37
+ - M1: Emit reranker telemetry on failure path
38
+ - M2: Default limit for `getEventsByTimeRange` raw-window path in searchV2 (50)
39
+ - M3: Split profile entity `$lookup` `$or` into two `$eq` lookups (merged with C2)
40
+ - M4: Replace `$push` + client-side percentiles with `$percentile` aggregation
41
+
42
+ ### Constraints Snapshot
43
+
44
+ - MongoDB-only (Community + mongot + atlas-local:preview)
45
+ - No new collections or search indexes
46
+ - Must not break existing 81/81 e2e tests or ~600+ unit tests
47
+ - TDD: write test first, then implement
48
+ - Fire-and-forget telemetry pattern via `emitTelemetry`
49
+ - `=== true` for disabled-by-default features
50
+ - DO NOT USE mongodb-agent-skills; use ONLY mcp**mongodb**search-knowledge MCP
51
+
52
+ ### In Scope
53
+
54
+ - All 15 fixes listed in Requirements Snapshot
55
+ - Tests for each fix
56
+ - Score normalization via manual RRF across search paths
57
+ - `bulkWrite` batch optimization for entity extraction
58
+ - `$percentile` server-side aggregation for latency stats
59
+
60
+ ### Out Of Scope
61
+
62
+ - Change Stream watcher for async LLM enrichment (deferred — needs separate design phase)
63
+ - `$rankFusion`/`$scoreFusion` for cross-path fusion (not a version issue — these operators only work on a single collection; ClawMongo merges results from multiple collections, so manual RRF remains the correct approach)
64
+ - LLM function injection from agent runtime (architectural seam — runtime doesn't expose LLM callable to memory layer yet)
65
+ - New collections, new search indexes
66
+
67
+ ### Planning Mode
68
+
69
+ - Plan mode: `execution_plan`
70
+ - Verification rigor: `standard`
71
+
72
+ ### Open Decisions
73
+
74
+ - None
75
+
76
+ ### Differences From Agreement
77
+
78
+ - None
79
+
80
+ ### Recommended Defaults
81
+
82
+ - RRF constant k=60 (standard from original RRF paper, matches existing `mongodb-hybrid.ts`)
83
+ - Rerank fetch timeout: 10 seconds (generous for cross-encoder API call over network)
84
+ - Raw-window event limit: 50 (balances context window budget vs recency)
85
+ - Cache TTL mapping: vector/hybrid -> `conversationTtlSec`, kb -> `kbTtlSec`, structured/episodic/graph -> `conversationTtlSec`, profile -> `kbTtlSec`
86
+ - Synonym expansion max ratio: 3x (original word count)
87
+
88
+ ### Current State
89
+
90
+ - `src/memory/mongodb-reranker.ts:81` — `fetch()` with no timeout or AbortSignal
91
+ - `src/memory/mongodb-manager.ts:2688-3026` — `searchV2` merges raw scores from different paths (vector 0-1, BM25 0-inf, episode 0.85-synthetic, graph 0.25-0.9 synthetic)
92
+ - `src/memory/mongodb-profile.ts:165-183` — `$lookup` with `$or` in `$expr` (cannot use index)
93
+ - `src/memory/mongodb-manager.ts` — no `synthesizeProfile` delegation method
94
+ - `src/memory/mongodb-graph.ts:898-913` — sequential `upsertEntity()` in loop (N+1)
95
+ - `src/memory/mongodb-graph.ts:917-955` — sequential `upsertRelation()` + `upsertEntityLink()` in loop
96
+ - `src/memory/mongodb-entity-extractor.ts:170-207` — `LLMEntityExtractor` class exists but config never creates it
97
+ - `src/memory/backend-config.ts:354-363` — `entityExtraction` config fields resolved but never consumed
98
+ - `src/memory/mongodb-query-rewriter.ts:137-143` — "llm"/"hyde" silently fall back to synonym-expansion
99
+ - `src/memory/mongodb-manager.ts:817-818` — cache TTL uses static `kbTtlSec` vs `conversationTtlSec` based on `kb.enabled`, not actual paths used
100
+ - `src/memory/mongodb-reranker.ts:78` — sends all candidate snippets to reranker including empty graph strings
101
+ - `src/memory/mongodb-telemetry.ts:20` — `"entity-extraction"` operation defined but never emitted
102
+ - `src/memory/mongodb-query-rewriter.ts:32-45` — `api: ["endpoint", "route", "rest"]` cross-domain expansion
103
+ - `src/memory/mongodb-reranker.ts:141-143` — catch block doesn't emit telemetry
104
+ - `src/memory/mongodb-telemetry.ts:89-112` — `getLatencyStats` loads all durations into client memory
105
+
106
+ ### Alternatives
107
+
108
+ - Score normalization: Could use min-max normalization per batch instead of RRF. RRF is simpler, more robust, and already implemented in `mongodb-hybrid.ts`.
109
+ - Entity batch: Could use transactions instead of `bulkWrite`. `bulkWrite` is simpler and sufficient for independent upserts.
110
+
111
+ ### Drawbacks
112
+
113
+ - Manual RRF discards magnitude information (a score of 0.99 vs 0.50 both become rank-based). Acceptable tradeoff — raw scores were already incomparable across paths.
114
+ - `$percentile` is approximate (t-digest algorithm). Acceptable — telemetry stats don't need exact values.
115
+ - Removing aggressive synonym expansions may slightly reduce recall for abbreviated queries. Acceptable — false positives were worse than missed expansions.
116
+
117
+ ### Critical-Path Verification Design
118
+
119
+ - Behavior contract: Not required
120
+ - Edge-case catalog: Concise — empty results, single-result paths, all-paths-fail, empty snippets, zero-entity extraction
121
+ - Provable properties: None
122
+ - Purity boundary map: Not required
123
+ - Verification strategy: Unit tests per fix + existing e2e regression
124
+
125
+ ---
126
+
127
+ ## Relevant Codebase Files
128
+
129
+ ### Files to Modify
130
+
131
+ - `src/memory/mongodb-reranker.ts` — timeout + empty snippet filter + failure telemetry (C1, H5, M1)
132
+ - `src/memory/mongodb-manager.ts` — RRF normalization in searchV2 + cache TTL from paths + raw-window limit + synthesizeProfile method (C3, H4, M2, C2-manager)
133
+ - `src/memory/mongodb-profile.ts` — split $or $lookup into two indexed $eq lookups (C2/M3)
134
+ - `src/memory/mongodb-graph.ts` — bulkWrite for entity/relation upserts + entity-extraction telemetry (H1, H6)
135
+ - `src/memory/mongodb-entity-extractor.ts` — document LLM stub clearly (H2)
136
+ - `src/memory/backend-config.ts` — add log warning for entity extraction config (H2)
137
+ - `src/memory/mongodb-query-rewriter.ts` — throw on unimplemented methods + clean synonym map (H3, H7)
138
+ - `src/memory/mongodb-telemetry.ts` — $percentile aggregation (M4)
139
+ - `src/memory/mongodb-query-cache.ts` — no changes needed (TTL logic change is in manager)
140
+
141
+ ### Test Files to Modify/Create
142
+
143
+ - `src/memory/mongodb-reranker.test.ts` — new or extended (C1, H5, M1)
144
+ - `src/memory/mongodb-manager.test.ts` — extended (C3, H4, M2, C2-manager)
145
+ - `src/memory/mongodb-profile.test.ts` — new (C2/M3)
146
+ - `src/memory/mongodb-graph.test.ts` — extended (H1, H6)
147
+ - `src/memory/mongodb-entity-extractor.test.ts` — extended (H2)
148
+ - `src/memory/backend-config.test.ts` — extended (H2)
149
+ - `src/memory/mongodb-query-rewriter.test.ts` — new or extended (H3, H7)
150
+ - `src/memory/mongodb-telemetry.test.ts` — extended (M4)
151
+
152
+ ### Patterns to Follow
153
+
154
+ - `src/memory/mongodb-hybrid.ts` (lines 48-66) — existing RRF scoring functions (rrfScore, normalizeVectorScore, normalizeBM25Score)
155
+ - `src/memory/mongodb-telemetry.ts` (lines 58-65) — fire-and-forget emitTelemetry pattern
156
+ - `src/memory/mongodb-graph.ts` (lines 182-229) — upsertEntity pattern (convert to bulkWrite)
157
+
158
+ ---
159
+
160
+ ## Phase 1: CRITICAL Fixes (C1 + C2 + C3)
161
+
162
+ > **Exit Criteria:** Reranker fetch has timeout. Profile $lookup uses indexed queries. searchV2 normalizes scores via RRF. All existing tests pass.
163
+
164
+ ### Task 1.1: Reranker Fetch Timeout (C1)
165
+
166
+ **Files:**
167
+
168
+ - Modify: `src/memory/mongodb-reranker.ts:81`
169
+ - Test: `src/memory/mongodb-reranker.test.ts`
170
+
171
+ **Step 1: Write failing test**
172
+
173
+ Test that `crossEncoderRerank` aborts when the fetch takes longer than 10 seconds.
174
+ Use a mock server or mock `fetch` that never resolves, verify the function returns fallback results within a reasonable timeframe.
175
+
176
+ ```typescript
177
+ test("crossEncoderRerank aborts on fetch timeout", async () => {
178
+ // Mock fetch that hangs
179
+ const originalFetch = globalThis.fetch;
180
+ globalThis.fetch = vi.fn(() => new Promise(() => {})); // never resolves
181
+ try {
182
+ const result = await crossEncoderRerank({
183
+ db: mockDb,
184
+ prefix: "test_",
185
+ agentId: "agent1",
186
+ query: "test query",
187
+ results: twoResults,
188
+ config: { ...defaultConfig, enabled: true, voyageApiKey: "pa-test" },
189
+ });
190
+ // Should fall back gracefully, not hang
191
+ expect(result.reranked).toBe(false);
192
+ expect(result.results).toEqual(twoResults);
193
+ } finally {
194
+ globalThis.fetch = originalFetch;
195
+ }
196
+ }, 15_000); // test timeout > rerank timeout
197
+ ```
198
+
199
+ **Step 2: Run test, verify it fails (hangs or times out)**
200
+
201
+ Run: `pnpm test -- src/memory/mongodb-reranker.test.ts`
202
+ Expected: Test hangs/times out because fetch has no timeout.
203
+
204
+ **Step 3: Implement `AbortSignal.timeout(10_000)` on fetch**
205
+
206
+ In `src/memory/mongodb-reranker.ts`, add signal to the fetch call at line 81:
207
+
208
+ ```typescript
209
+ const response = await fetch(rerankUrl, {
210
+ method: "POST",
211
+ headers: {
212
+ "Content-Type": "application/json",
213
+ Authorization: `Bearer ${config.voyageApiKey}`,
214
+ },
215
+ body: JSON.stringify({
216
+ model: config.model,
217
+ query: config.instruction ? `${config.instruction}\n${query}` : query,
218
+ documents,
219
+ top_k: candidates.length,
220
+ }),
221
+ signal: AbortSignal.timeout(10_000),
222
+ });
223
+ ```
224
+
225
+ **Step 4: Run test, verify it passes**
226
+
227
+ Run: `pnpm test -- src/memory/mongodb-reranker.test.ts`
228
+ Expected: PASS — function returns fallback within timeout.
229
+
230
+ ### Task 1.2: Profile $lookup Index Fix (C2/M3)
231
+
232
+ **Files:**
233
+
234
+ - Modify: `src/memory/mongodb-profile.ts:165-183`
235
+ - Test: `src/memory/mongodb-profile.test.ts` (new or extend)
236
+
237
+ **Step 1: Write test**
238
+
239
+ Test that `synthesizeProfile` returns correct `topEntities` when relations reference entities via both `fromEntityId` and `toEntityId`. Verify the pipeline produces the same results as before (functional equivalence).
240
+
241
+ **Step 2: Implement the split**
242
+
243
+ Replace the single `$lookup` with `$or` (lines 165-183 of `mongodb-profile.ts`) with two separate `$lookup` stages, each using `$count` inside the sub-pipeline (memory-efficient — no full relation docs materialized):
244
+
245
+ ```typescript
246
+ // Lookup 1: outgoing relations count (uses index on fromEntityId)
247
+ {
248
+ $lookup: {
249
+ from: `${prefix}relations`,
250
+ let: { eid: "$entityId" },
251
+ pipeline: [
252
+ { $match: { $expr: { $eq: ["$fromEntityId", "$$eid"] }, ...scopeFilter } },
253
+ { $count: "cnt" },
254
+ ],
255
+ as: "outRels",
256
+ },
257
+ },
258
+ // Lookup 2: incoming relations count (uses index on toEntityId)
259
+ {
260
+ $lookup: {
261
+ from: `${prefix}relations`,
262
+ let: { eid: "$entityId" },
263
+ pipeline: [
264
+ { $match: { $expr: { $eq: ["$toEntityId", "$$eid"] }, ...scopeFilter } },
265
+ { $count: "cnt" },
266
+ ],
267
+ as: "inRels",
268
+ },
269
+ },
270
+ // Sum the two counts (no full relation docs in memory)
271
+ {
272
+ $addFields: {
273
+ relationCount: {
274
+ $add: [
275
+ { $ifNull: [{ $arrayElemAt: ["$outRels.cnt", 0] }, 0] },
276
+ { $ifNull: [{ $arrayElemAt: ["$inRels.cnt", 0] }, 0] },
277
+ ],
278
+ },
279
+ },
280
+ },
281
+ ```
282
+
283
+ **IMPORTANT:** This requires a compound index on `{ toEntityId: 1, agentId: 1, scope: 1, scopeRef: 1 }` in the relations collection. The existing index only covers `fromEntityId`. See Task 1.2b below.
284
+
285
+ **Step 3: Run tests**
286
+
287
+ Run: `pnpm test -- src/memory/mongodb-profile.test.ts`
288
+ Expected: PASS
289
+
290
+ ### Task 1.2b: Add toEntityId Compound Index to Relations Collection
291
+
292
+ **Files:**
293
+
294
+ - Modify: `src/memory/mongodb-schema.ts` (RELATIONS_INDEXES array)
295
+ - Test: `src/memory/mongodb-schema.test.ts`
296
+
297
+ **Why:** The existing relations index covers `{ agentId, scope, scopeRef, fromEntityId, type }` but the new split $lookup for incoming relations needs `toEntityId` as a prefix key. Without this, the incoming lookup still does a COLLSCAN. Research ref: M4 — "$expr in $lookup only uses indexes for $eq comparisons."
298
+
299
+ **Step 1: Add index**
300
+
301
+ Add to `RELATIONS_INDEXES` in `mongodb-schema.ts`:
302
+
303
+ ```typescript
304
+ { key: { toEntityId: 1, agentId: 1, scope: 1, scopeRef: 1 }, name: "idx_relations_to_entity_scope" },
305
+ ```
306
+
307
+ **Step 2: Update EXPECTED_STANDARD_INDEX_COUNT**
308
+
309
+ Increment the count in schema tests and e2e tests (currently 58 → 59).
310
+
311
+ **Step 3: Run tests**
312
+
313
+ Run: `pnpm test -- src/memory/mongodb-schema.test.ts`
314
+ Expected: PASS
315
+
316
+ ### Task 1.3: Add synthesizeProfile to Manager (C2-manager)
317
+
318
+ **Files:**
319
+
320
+ - Modify: `src/memory/mongodb-manager.ts`
321
+ - Test: `src/memory/mongodb-manager.test.ts`
322
+
323
+ **Step 1: Write test**
324
+
325
+ ```typescript
326
+ test("synthesizeProfile delegates to standalone function", async () => {
327
+ // Mock the standalone synthesizeProfile
328
+ const result = await manager.synthesizeProfile({ scope: "agent", scopeRef: "agent1" });
329
+ expect(result).toBeDefined();
330
+ expect(result.agentId).toBe("agent1");
331
+ });
332
+ ```
333
+
334
+ **Step 2: Implement delegation**
335
+
336
+ Add a `synthesizeProfile` method to `MongoDBMemoryManager` that delegates to the standalone `synthesizeProfile` function from `mongodb-profile.ts`:
337
+
338
+ ```typescript
339
+ async synthesizeProfile(params: {
340
+ scope?: MemoryScope;
341
+ scopeRef?: string;
342
+ maxPerType?: number;
343
+ maxEntities?: number;
344
+ maxEpisodes?: number;
345
+ activityWindowMs?: number;
346
+ }): Promise<ProfileSynthesis> {
347
+ return synthesizeProfile({
348
+ db: this.db,
349
+ prefix: this.prefix,
350
+ agentId: this.agentId,
351
+ scope: params.scope ?? "agent",
352
+ scopeRef: params.scopeRef ?? this.agentScopeRef,
353
+ maxPerType: params.maxPerType,
354
+ maxEntities: params.maxEntities,
355
+ maxEpisodes: params.maxEpisodes,
356
+ activityWindowMs: params.activityWindowMs,
357
+ });
358
+ }
359
+ ```
360
+
361
+ **Step 3: Run tests**
362
+
363
+ Run: `pnpm test -- src/memory/mongodb-manager.test.ts`
364
+ Expected: PASS
365
+
366
+ ### Task 1.4: Score Normalization via Manual RRF (C3)
367
+
368
+ **Files:**
369
+
370
+ - Modify: `src/memory/mongodb-manager.ts:2688-2996` (searchV2 function)
371
+ - Test: `src/memory/mongodb-manager.test.ts`
372
+
373
+ **IMPORTANT:** `MemorySearchResult.filePath` is OPTIONAL. The deduplication function `deduplicateSearchResults` uses `result.snippet` as the dedup key. Use `snippet` (not `filePath`) as the RRF map key.
374
+
375
+ **Step 1: Structural change — preserve per-path result lists**
376
+
377
+ Currently `searchV2` accumulates all results into a flat `results: MemorySearchResult[]` array. To apply per-path RRF, we must also keep per-path lists:
378
+
379
+ ```typescript
380
+ // Add alongside existing `const results: MemorySearchResult[] = []`
381
+ const perPathResults: Record<string, MemorySearchResult[]> = {};
382
+
383
+ // In each path's try/catch block, after `results.push(...pathResults)`, also:
384
+ perPathResults[path.path] = pathResults;
385
+ ```
386
+
387
+ This applies to ALL paths including backstop paths (procedural backstop ~line 2943-2967, hybrid backstop ~line 2969-2996). Backstop paths must also track their results in `perPathResults`.
388
+
389
+ **Step 2: Write tests**
390
+
391
+ ```typescript
392
+ describe("searchV2 score normalization", () => {
393
+ test("results from different paths are RRF-normalized", async () => {
394
+ // Setup: mock paths to return results with different score ranges
395
+ const result = await searchV2(...);
396
+ // All final scores should be RRF-based, in (0, 1] range
397
+ for (const r of result.results) {
398
+ expect(r.score).toBeGreaterThan(0);
399
+ expect(r.score).toBeLessThanOrEqual(1);
400
+ }
401
+ });
402
+
403
+ test("single-path results preserve relative ordering", async () => {
404
+ // When only one path returns results, rank ordering is preserved
405
+ });
406
+
407
+ test("backstop path results are also RRF-normalized", async () => {
408
+ // When backstop fires, its results should also get RRF scores
409
+ });
410
+ });
411
+ ```
412
+
413
+ **Step 3: Implement RRF normalization AFTER ALL paths (including backstops)**
414
+
415
+ Place this code AFTER the hybrid backstop block (~line 2996) and BEFORE the final `rerankResults` call:
416
+
417
+ ```typescript
418
+ import { rrfScore } from "./mongodb-hybrid.js";
419
+
420
+ // RRF normalization: replace raw scores with rank-based scores, summed across paths
421
+ // Uses `snippet` as the dedup key (matches deduplicateSearchResults behavior)
422
+ const rrfMap = new Map<string, number>();
423
+ for (const [_pathName, pathResults] of Object.entries(perPathResults)) {
424
+ // Each path's results are already sorted by native score descending
425
+ for (let rank = 0; rank < pathResults.length; rank++) {
426
+ const key = pathResults[rank].snippet;
427
+ rrfMap.set(key, (rrfMap.get(key) ?? 0) + rrfScore(rank + 1));
428
+ }
429
+ }
430
+
431
+ // Apply fused RRF scores back to the flat results array before dedup
432
+ for (const r of results) {
433
+ const rrfVal = rrfMap.get(r.snippet);
434
+ if (rrfVal !== undefined) r.score = rrfVal;
435
+ }
436
+
437
+ // Dedup then re-sort by fused score (existing deduplicateSearchResults call)
438
+ const deduped = deduplicateSearchResults(results);
439
+ deduped.sort((a, b) => b.score - a.score);
440
+ ```
441
+
442
+ **Step 3: Run tests**
443
+
444
+ Run: `pnpm test -- src/memory/mongodb-manager.test.ts`
445
+ Expected: PASS
446
+
447
+ **Step 4: Commit Phase 1**
448
+
449
+ ```bash
450
+ scripts/committer "Fix(memory): CRITICAL audit fixes — rerank timeout, profile $lookup index, RRF score normalization, synthesizeProfile delegation" \
451
+ src/memory/mongodb-reranker.ts \
452
+ src/memory/mongodb-profile.ts \
453
+ src/memory/mongodb-manager.ts \
454
+ src/memory/mongodb-reranker.test.ts \
455
+ src/memory/mongodb-profile.test.ts \
456
+ src/memory/mongodb-manager.test.ts
457
+ ```
458
+
459
+ ---
460
+
461
+ ## Phase 2: HIGH Fixes — Dead Code + Config (H2, H3)
462
+
463
+ > **Exit Criteria:** LLM entity extractor config is honest about stub status. Query rewriter throws on unimplemented methods. Entity extraction config logs warning.
464
+
465
+ ### Task 2.1: LLMEntityExtractor Config Honesty (H2)
466
+
467
+ **Files:**
468
+
469
+ - Modify: `src/memory/backend-config.ts:354-363`
470
+ - Modify: `src/memory/mongodb-entity-extractor.ts` (add clear documentation)
471
+ - Test: `src/memory/backend-config.test.ts`
472
+
473
+ **Step 1: Write test**
474
+
475
+ ```typescript
476
+ test("resolveMongoDBConfig logs warning when entityExtraction.method is 'llm' but no LLM function available", () => {
477
+ // Config with method: "llm" should produce a resolved config with a warning log
478
+ const spy = vi.spyOn(log, "warn");
479
+ const resolved = resolveMongoDBConfig({
480
+ graph: { entityExtraction: { method: "llm" } },
481
+ });
482
+ expect(spy).toHaveBeenCalledWith(
483
+ expect.stringContaining(
484
+ "entity extraction method 'llm' configured but LLM function not injected",
485
+ ),
486
+ );
487
+ // Config field stays as-is (method: "llm") for future injection
488
+ expect(resolved.graph.entityExtraction.method).toBe("llm");
489
+ });
490
+ ```
491
+
492
+ **Step 2: Implement warning**
493
+
494
+ In `backend-config.ts`, after resolving `graph.entityExtraction`, add:
495
+
496
+ ```typescript
497
+ if (resolved.graph.entityExtraction.method === "llm") {
498
+ log.warn(
499
+ "entity extraction method 'llm' configured but LLM function not injected — regex extractor will be used at runtime. " +
500
+ "Set graph.entityExtraction.method to 'regex' to suppress this warning.",
501
+ );
502
+ }
503
+ ```
504
+
505
+ **Step 3: Run tests**
506
+
507
+ Run: `pnpm test -- src/memory/backend-config.test.ts`
508
+ Expected: PASS
509
+
510
+ ### Task 2.2: Query Rewriter Validation Error (H3)
511
+
512
+ **Files:**
513
+
514
+ - Modify: `src/memory/mongodb-query-rewriter.ts:131-148`
515
+ - Test: `src/memory/mongodb-query-rewriter.test.ts` (new or extend)
516
+
517
+ **Step 1: Write tests**
518
+
519
+ ```typescript
520
+ test("rewriteQuery throws ConfigValidationError for 'llm' method", async () => {
521
+ await expect(
522
+ rewriteQuery({
523
+ db: mockDb,
524
+ prefix: "test_",
525
+ agentId: "a1",
526
+ query: "test",
527
+ config: { enabled: true, method: "llm", maxTokens: 128 },
528
+ }),
529
+ ).rejects.toThrow(/not yet implemented/);
530
+ });
531
+
532
+ test("rewriteQuery throws ConfigValidationError for 'hyde' method", async () => {
533
+ await expect(
534
+ rewriteQuery({
535
+ db: mockDb,
536
+ prefix: "test_",
537
+ agentId: "a1",
538
+ query: "test",
539
+ config: { enabled: true, method: "hyde", maxTokens: 128 },
540
+ }),
541
+ ).rejects.toThrow(/not yet implemented/);
542
+ });
543
+ ```
544
+
545
+ **Step 2: Implement validation error**
546
+
547
+ Replace the silent fallback in `mongodb-query-rewriter.ts` lines 137-143:
548
+
549
+ ```typescript
550
+ case "llm":
551
+ case "hyde":
552
+ throw new Error(
553
+ `Query rewrite method "${config.method}" is not yet implemented. ` +
554
+ `Use "synonym-expansion" or disable query rewriting (queryRewriting.enabled: false).`,
555
+ );
556
+ ```
557
+
558
+ **Step 3: Run tests**
559
+
560
+ Run: `pnpm test -- src/memory/mongodb-query-rewriter.test.ts`
561
+ Expected: PASS
562
+
563
+ ### Task 2.3: Clean Up Aggressive Synonym Expansions (H7)
564
+
565
+ **Files:**
566
+
567
+ - Modify: `src/memory/mongodb-query-rewriter.ts:32-45`
568
+ - Test: `src/memory/mongodb-query-rewriter.test.ts`
569
+
570
+ **Step 1: Write tests**
571
+
572
+ ```typescript
573
+ test("'api' does not expand to unrelated domains", () => {
574
+ const result = expandSynonyms("api");
575
+ expect(result).not.toContain("route");
576
+ expect(result).not.toContain("rest");
577
+ // Should only contain api (original) + direct abbreviation expansions
578
+ });
579
+
580
+ test("expansion respects max ratio of 3x original word count", () => {
581
+ const result = expandSynonyms("auth db api");
582
+ const originalCount = 3;
583
+ const expandedCount = result.split(/\s+/).length;
584
+ expect(expandedCount).toBeLessThanOrEqual(originalCount * 3);
585
+ });
586
+ ```
587
+
588
+ **Step 2: Implement**
589
+
590
+ 1. Remove cross-domain expansions from SYNONYM_MAP:
591
+ - `api: ["endpoint", "route", "rest"]` -> REMOVE entirely (api is not a synonym of route/rest)
592
+ - `ui: ["interface", "frontend", "component"]` -> REMOVE (too broad)
593
+ - Keep domain-specific: `auth`, `db`, `bug`, `perf`, `config`, `deps`, `deploy`, `docs`, `test`, `refactor`
594
+
595
+ **NOTE:** Existing tests in `mongodb-query-rewriter.test.ts` likely assert "api" expands to include "endpoint". Those tests MUST be updated to match the new SYNONYM_MAP. This is expected — the old behavior was wrong (cross-domain false positives).
596
+
597
+ 2. Add max expansion ratio cap (3x):
598
+
599
+ ```typescript
600
+ export function expandSynonyms(query: string): string {
601
+ const words = query.toLowerCase().split(/\s+/).filter(Boolean);
602
+ const expanded = new Set(words);
603
+ const maxExpanded = words.length * 3;
604
+
605
+ for (const word of words) {
606
+ if (expanded.size >= maxExpanded) break;
607
+ const abbr = ABBREVIATION_MAP[word];
608
+ if (abbr) expanded.add(abbr);
609
+ const syns = SYNONYM_MAP[word];
610
+ if (syns) {
611
+ for (const syn of syns) {
612
+ if (expanded.size >= maxExpanded) break;
613
+ expanded.add(syn);
614
+ }
615
+ }
616
+ }
617
+
618
+ return [...expanded].join(" ");
619
+ }
620
+ ```
621
+
622
+ **Step 3: Run tests**
623
+
624
+ Run: `pnpm test -- src/memory/mongodb-query-rewriter.test.ts`
625
+ Expected: PASS
626
+
627
+ **Step 4: Commit Phase 2**
628
+
629
+ ```bash
630
+ scripts/committer "Fix(memory): HIGH audit fixes — entity extractor config honesty, query rewriter validation, synonym cleanup" \
631
+ src/memory/backend-config.ts \
632
+ src/memory/mongodb-entity-extractor.ts \
633
+ src/memory/mongodb-query-rewriter.ts \
634
+ src/memory/backend-config.test.ts \
635
+ src/memory/mongodb-query-rewriter.test.ts
636
+ ```
637
+
638
+ ---
639
+
640
+ ## Phase 3: HIGH Fixes — Performance + Telemetry (H1, H4, H5, H6)
641
+
642
+ > **Exit Criteria:** Entity upserts use bulkWrite. Cache TTL derived from paths. Empty snippets filtered from reranker. Entity-extraction telemetry emitted.
643
+
644
+ ### Task 3.1: bulkWrite for Entity Upserts (H1)
645
+
646
+ **Files:**
647
+
648
+ - Modify: `src/memory/mongodb-graph.ts:896-955` (extractAndUpsertEntities)
649
+ - Test: `src/memory/mongodb-graph.test.ts`
650
+
651
+ **Step 1: Write test**
652
+
653
+ ```typescript
654
+ test("extractAndUpsertEntities uses bulkWrite for entities", async () => {
655
+ const bulkWriteSpy = vi.spyOn(entitiesCol, "bulkWrite");
656
+ await extractAndUpsertEntities({
657
+ db: mockDb,
658
+ prefix: "test_",
659
+ agentId: "a1",
660
+ eventContent: "@alice mentioned @bob working on #projectX",
661
+ scope: "agent",
662
+ sourceEventId: "ev1",
663
+ });
664
+ // Should call bulkWrite once instead of N sequential upsertEntity calls
665
+ expect(bulkWriteSpy).toHaveBeenCalledTimes(1);
666
+ const ops = bulkWriteSpy.mock.calls[0][0];
667
+ expect(ops.length).toBeGreaterThanOrEqual(2); // at least alice + bob
668
+ // Each op should be updateOne with upsert: true
669
+ for (const op of ops) {
670
+ expect(op).toHaveProperty("updateOne");
671
+ expect(op.updateOne.upsert).toBe(true);
672
+ }
673
+ });
674
+ ```
675
+
676
+ **Step 2: Implement bulkWrite**
677
+
678
+ Replace the sequential entity upsert loop (lines 898-913) with:
679
+
680
+ ```typescript
681
+ // Batch upsert entities via bulkWrite
682
+ const entityOps = extracted.map((entity) => ({
683
+ updateOne: {
684
+ filter: { entityId: entity.entityId, agentId, scope, scopeRef },
685
+ update: {
686
+ $set: {
687
+ entityId: entity.entityId,
688
+ name: entity.name,
689
+ type: entity.type,
690
+ agentId,
691
+ scope,
692
+ scopeRef,
693
+ updatedAt: new Date(),
694
+ ...(sourceEventId ? { sourceEventIds: [sourceEventId] } : {}),
695
+ },
696
+ $setOnInsert: { createdAt: new Date() },
697
+ },
698
+ upsert: true,
699
+ },
700
+ }));
701
+ if (entityOps.length > 0) {
702
+ await entitiesCollection(db, prefix).bulkWrite(entityOps, { ordered: false });
703
+ }
704
+ ```
705
+
706
+ Similarly, batch the relation + entity-link upserts into two `bulkWrite` calls.
707
+
708
+ **CRITICAL: Preserve existing logic.** The pairwise loop (lines 918-955) uses `inferEntityLinkType`, `canonicalizeEntityPair`, `makeEntityLinkId`, and the 6-field compound filter for entity links. The bulkWrite conversion must replicate the EXACT filter/update from `upsertRelation` and `upsertEntityLink` — just batch them. Also preserve the bounded loop indices (`i < 5`, `j < 6`).
709
+
710
+ ```typescript
711
+ // Build ops from the pairwise loop (same logic, batched)
712
+ const relationOps = [];
713
+ const linkOps = [];
714
+ for (let i = 0; i < Math.min(extracted.length - 1, 5); i++) {
715
+ for (let j = i + 1; j < Math.min(extracted.length, 6); j++) {
716
+ // ... inferEntityLinkType, canonicalizeEntityPair, makeEntityLinkId ...
717
+ // ... same filter/update as existing upsertRelation/upsertEntityLink ...
718
+ relationOps.push({
719
+ updateOne: {
720
+ filter: {
721
+ /* existing fields */
722
+ },
723
+ update: {
724
+ /* existing $set/$setOnInsert */
725
+ },
726
+ upsert: true,
727
+ },
728
+ });
729
+ linkOps.push({
730
+ updateOne: {
731
+ filter: {
732
+ /* existing 6-field filter */
733
+ },
734
+ update: {
735
+ /* existing fields */
736
+ },
737
+ upsert: true,
738
+ },
739
+ });
740
+ }
741
+ }
742
+ if (relationOps.length > 0) {
743
+ await relationsCollection(db, prefix).bulkWrite(relationOps, { ordered: false });
744
+ }
745
+ if (linkOps.length > 0) {
746
+ await entityLinksCollection(db, prefix).bulkWrite(linkOps, { ordered: false });
747
+ }
748
+ ```
749
+
750
+ **Error handling for partial failures:** `bulkWrite` with `ordered: false` may succeed partially. Wrap in try/catch and log `BulkWriteError.writeErrors` with `log.warn`.
751
+
752
+ **Step 3: Run tests**
753
+
754
+ Run: `pnpm test -- src/memory/mongodb-graph.test.ts`
755
+ Expected: PASS
756
+
757
+ ### Task 3.2: Cache TTL from Path (H4)
758
+
759
+ **Files:**
760
+
761
+ - Modify: `src/memory/mongodb-manager.ts:816-831`
762
+ - Test: `src/memory/mongodb-manager.test.ts`
763
+
764
+ **Step 1: Write test**
765
+
766
+ ```typescript
767
+ test("cache TTL uses kbTtlSec when kb path was executed", () => {
768
+ // When pathsExecuted includes "kb", TTL should use kbTtlSec
769
+ });
770
+
771
+ test("cache TTL uses conversationTtlSec when only conversation paths executed", () => {
772
+ // When pathsExecuted is ["hybrid", "structured"], TTL should use conversationTtlSec
773
+ });
774
+ ```
775
+
776
+ **Step 2: Implement**
777
+
778
+ Replace the static TTL derivation at line 817-818:
779
+
780
+ ```typescript
781
+ // Derive TTL from actual paths executed (not static config)
782
+ const hasKbPath = v2.metadata.pathsExecuted.includes("kb");
783
+ const ttlSec = hasKbPath ? mongoCfg.cache.kbTtlSec : mongoCfg.cache.conversationTtlSec;
784
+ ```
785
+
786
+ **Step 3: Run tests**
787
+
788
+ Run: `pnpm test -- src/memory/mongodb-manager.test.ts`
789
+ Expected: PASS
790
+
791
+ ### Task 3.3: Filter Empty Snippets Before Reranking (H5)
792
+
793
+ **Files:**
794
+
795
+ - Modify: `src/memory/mongodb-reranker.ts:78`
796
+ - Test: `src/memory/mongodb-reranker.test.ts`
797
+
798
+ **Step 1: Write test**
799
+
800
+ ```typescript
801
+ test("crossEncoderRerank filters out results with empty/blank snippets", async () => {
802
+ const results = [
803
+ { snippet: "Alice works on ProjectX", score: 0.9 /* ... */ },
804
+ { snippet: "", score: 0.8 /* ... */ }, // empty — should be filtered
805
+ { snippet: " ", score: 0.7 /* ... */ }, // blank — should be filtered
806
+ { snippet: "Bob manages TeamY", score: 0.6 /* ... */ },
807
+ ];
808
+ // Mock fetch to return reranked indices for non-empty docs only
809
+ // Verify only 2 documents sent to API, empty results appended at end
810
+ });
811
+ ```
812
+
813
+ **Step 2: Implement**
814
+
815
+ Before building the `documents` array for the API call, filter empty snippets:
816
+
817
+ ```typescript
818
+ // Filter out candidates with empty/blank snippets (graph relations can produce near-empty text)
819
+ const validCandidates = candidates.filter((r) => r.snippet.trim().length > 0);
820
+ const emptySnippetCandidates = candidates.filter((r) => r.snippet.trim().length === 0);
821
+
822
+ if (validCandidates.length <= 1) {
823
+ return { results, reranked: false, latencyMs: 0 };
824
+ }
825
+
826
+ const documents = validCandidates.map((r) => r.snippet);
827
+ ```
828
+
829
+ After reranking, append emptySnippetCandidates before overflow and below:
830
+
831
+ ```typescript
832
+ return {
833
+ results: [...reranked, ...emptySnippetCandidates, ...overflow, ...below],
834
+ reranked: true,
835
+ latencyMs,
836
+ };
837
+ ```
838
+
839
+ **Step 3: Run tests**
840
+
841
+ Run: `pnpm test -- src/memory/mongodb-reranker.test.ts`
842
+ Expected: PASS
843
+
844
+ ### Task 3.4: Entity-Extraction Telemetry (H6)
845
+
846
+ **Files:**
847
+
848
+ - Modify: `src/memory/mongodb-graph.ts` (extractAndUpsertEntities)
849
+ - Test: `src/memory/mongodb-graph.test.ts`
850
+
851
+ **Step 1: Write test**
852
+
853
+ ```typescript
854
+ test("extractAndUpsertEntities emits entity-extraction telemetry", async () => {
855
+ const telemetrySpy = vi.spyOn(telemetryModule, "emitTelemetry");
856
+ await extractAndUpsertEntities({
857
+ db: mockDb,
858
+ prefix: "test_",
859
+ agentId: "a1",
860
+ eventContent: "@alice",
861
+ scope: "agent",
862
+ });
863
+ expect(telemetrySpy).toHaveBeenCalledWith(
864
+ mockDb,
865
+ "test_",
866
+ expect.objectContaining({
867
+ meta: { agentId: "a1", operation: "entity-extraction" },
868
+ ok: true,
869
+ extractionMethod: "regex",
870
+ entitiesExtracted: 1,
871
+ }),
872
+ );
873
+ });
874
+ ```
875
+
876
+ **Step 2: Implement**
877
+
878
+ Add `emitTelemetry` calls to `extractAndUpsertEntities` in both success and failure paths:
879
+
880
+ ```typescript
881
+ // After successful extraction + upsert:
882
+ emitTelemetry(db, prefix, {
883
+ meta: { agentId, operation: "entity-extraction" },
884
+ durationMs: Date.now() - startMs,
885
+ ok: true,
886
+ extractionMethod: extractorResults[0]?.extractionMethod ?? "regex", // use result's method, not instanceof
887
+ entitiesExtracted: extracted.length,
888
+ });
889
+
890
+ // In catch block:
891
+ emitTelemetry(db, prefix, {
892
+ meta: { agentId, operation: "entity-extraction" },
893
+ durationMs: Date.now() - startMs,
894
+ ok: false,
895
+ extractionMethod: extractor instanceof RegexEntityExtractor ? "regex" : "llm",
896
+ entitiesExtracted: 0,
897
+ });
898
+ ```
899
+
900
+ **Step 3: Run tests**
901
+
902
+ Run: `pnpm test -- src/memory/mongodb-graph.test.ts`
903
+ Expected: PASS
904
+
905
+ **Step 4: Commit Phase 3**
906
+
907
+ ```bash
908
+ scripts/committer "Fix(memory): HIGH audit fixes — bulkWrite entity upserts, path-based cache TTL, empty snippet filter, entity-extraction telemetry" \
909
+ src/memory/mongodb-graph.ts \
910
+ src/memory/mongodb-manager.ts \
911
+ src/memory/mongodb-reranker.ts \
912
+ src/memory/mongodb-graph.test.ts \
913
+ src/memory/mongodb-manager.test.ts \
914
+ src/memory/mongodb-reranker.test.ts
915
+ ```
916
+
917
+ ---
918
+
919
+ ## Phase 4: MEDIUM Quick-Wins (M1, M2, M4)
920
+
921
+ > **Exit Criteria:** Reranker emits telemetry on failure. Raw-window events capped at 50. getLatencyStats uses $percentile.
922
+
923
+ ### Task 4.1: Reranker Failure Telemetry (M1)
924
+
925
+ **Files:**
926
+
927
+ - Modify: `src/memory/mongodb-reranker.ts:141-143`
928
+ - Test: `src/memory/mongodb-reranker.test.ts`
929
+
930
+ **Step 1: Write test**
931
+
932
+ ```typescript
933
+ test("crossEncoderRerank emits telemetry on failure", async () => {
934
+ globalThis.fetch = vi.fn(() => Promise.reject(new Error("network error")));
935
+ const telemetrySpy = vi.spyOn(telemetryModule, "emitTelemetry");
936
+ const result = await crossEncoderRerank({
937
+ /* valid params with enabled config */
938
+ });
939
+ expect(result.reranked).toBe(false);
940
+ expect(telemetrySpy).toHaveBeenCalledWith(
941
+ expect.anything(),
942
+ expect.anything(),
943
+ expect.objectContaining({ ok: false }),
944
+ );
945
+ });
946
+ ```
947
+
948
+ **Step 2: Implement**
949
+
950
+ Add `emitTelemetry` to the catch block in `crossEncoderRerank`:
951
+
952
+ ```typescript
953
+ } catch (err) {
954
+ log.warn("rerank failed, falling back to input order", { error: err });
955
+ emitTelemetry(db, prefix, {
956
+ meta: { agentId, operation: "rerank" },
957
+ durationMs: Date.now() - rerankStart,
958
+ ok: false,
959
+ rerankModel: config.model,
960
+ rerankLatencyMs: Date.now() - rerankStart,
961
+ });
962
+ return { results, reranked: false, latencyMs: Date.now() - rerankStart };
963
+ }
964
+ ```
965
+
966
+ **Step 3: Run tests**
967
+
968
+ Run: `pnpm test -- src/memory/mongodb-reranker.test.ts`
969
+ Expected: PASS
970
+
971
+ ### Task 4.2: Raw-Window Event Cap (M2)
972
+
973
+ **Files:**
974
+
975
+ - Modify: `src/memory/mongodb-manager.ts` (searchV2, raw-window case)
976
+ - Test: `src/memory/mongodb-manager.test.ts`
977
+
978
+ **Step 1: Write test**
979
+
980
+ ```typescript
981
+ test("searchV2 raw-window path caps events at 50", async () => {
982
+ // Mock getEventsByTimeRange to return 100 events
983
+ // Verify only 50 are used in pathResults
984
+ });
985
+ ```
986
+
987
+ **Step 2: Implement**
988
+
989
+ In the `raw-window` case of searchV2 (around line 2744), pass an explicit limit:
990
+
991
+ ```typescript
992
+ case "raw-window": {
993
+ const rawWindowLimit = 50;
994
+ const events = await getEventsByTimeRange({
995
+ db,
996
+ prefix,
997
+ agentId,
998
+ start: timeRange?.start ?? new Date(Date.now() - 24 * 60 * 60 * 1000),
999
+ end: timeRange?.end ?? new Date(),
1000
+ scope,
1001
+ scopeRef: agentScopeRef,
1002
+ limit: rawWindowLimit,
1003
+ });
1004
+ ```
1005
+
1006
+ Note: `getEventsByTimeRange` already accepts a `limit` parameter (default 1000). We just pass 50.
1007
+
1008
+ **Step 3: Run tests**
1009
+
1010
+ Run: `pnpm test -- src/memory/mongodb-manager.test.ts`
1011
+ Expected: PASS
1012
+
1013
+ ### Task 4.3: Server-Side $percentile for Latency Stats (M4)
1014
+
1015
+ **Files:**
1016
+
1017
+ - Modify: `src/memory/mongodb-telemetry.ts:89-112` (getLatencyStats)
1018
+ - Test: `src/memory/mongodb-telemetry.test.ts`
1019
+
1020
+ **Step 1: Write test**
1021
+
1022
+ ```typescript
1023
+ test("getLatencyStats uses $percentile aggregation", async () => {
1024
+ // Insert telemetry documents
1025
+ // Verify the aggregation pipeline uses $percentile instead of $push
1026
+ const spy = vi.spyOn(collection, "aggregate");
1027
+ await getLatencyStats({ db, prefix, agentId: "a1" });
1028
+ const pipeline = spy.mock.calls[0][0];
1029
+ // Verify no $push in $group, and $percentile is used
1030
+ const groupStage = pipeline.find((s) => s.$group);
1031
+ expect(groupStage.$group).not.toHaveProperty("durations");
1032
+ expect(groupStage.$group.p50).toBeDefined();
1033
+ });
1034
+ ```
1035
+
1036
+ **Step 2: Implement**
1037
+
1038
+ Replace the current `$push` + client-side percentile calculation with server-side `$percentile`:
1039
+
1040
+ ```typescript
1041
+ const pipeline = [
1042
+ { $match: matchStage },
1043
+ {
1044
+ $group: {
1045
+ _id: null,
1046
+ count: { $sum: 1 },
1047
+ p50: {
1048
+ $percentile: {
1049
+ input: "$durationMs",
1050
+ p: [0.5],
1051
+ method: "approximate",
1052
+ },
1053
+ },
1054
+ p95: {
1055
+ $percentile: {
1056
+ input: "$durationMs",
1057
+ p: [0.95],
1058
+ method: "approximate",
1059
+ },
1060
+ },
1061
+ p99: {
1062
+ $percentile: {
1063
+ input: "$durationMs",
1064
+ p: [0.99],
1065
+ method: "approximate",
1066
+ },
1067
+ },
1068
+ },
1069
+ },
1070
+ ];
1071
+
1072
+ const results = await telemetryCollection(db, prefix).aggregate(pipeline).toArray();
1073
+ if (results.length === 0 || results[0].count === 0) {
1074
+ return { p50: 0, p95: 0, p99: 0, count: 0 };
1075
+ }
1076
+
1077
+ return {
1078
+ p50: results[0].p50?.[0] ?? 0,
1079
+ p95: results[0].p95?.[0] ?? 0,
1080
+ p99: results[0].p99?.[0] ?? 0,
1081
+ count: results[0].count,
1082
+ };
1083
+ ```
1084
+
1085
+ Note: `$percentile` returns an array (one value per percentile requested). Since we request one percentile per field, we take index [0].
1086
+
1087
+ **Step 3: Run tests**
1088
+
1089
+ Run: `pnpm test -- src/memory/mongodb-telemetry.test.ts`
1090
+ Expected: PASS
1091
+
1092
+ **Step 4: Commit Phase 4**
1093
+
1094
+ ```bash
1095
+ scripts/committer "Fix(memory): MEDIUM audit fixes — reranker failure telemetry, raw-window event cap, $percentile latency stats" \
1096
+ src/memory/mongodb-reranker.ts \
1097
+ src/memory/mongodb-manager.ts \
1098
+ src/memory/mongodb-telemetry.ts \
1099
+ src/memory/mongodb-reranker.test.ts \
1100
+ src/memory/mongodb-manager.test.ts \
1101
+ src/memory/mongodb-telemetry.test.ts
1102
+ ```
1103
+
1104
+ ---
1105
+
1106
+ ## Phase 5: Final Validation
1107
+
1108
+ > **Exit Criteria:** All memory tests pass. Build succeeds. No regressions.
1109
+
1110
+ ### Task 5.1: Full Test Suite
1111
+
1112
+ **Step 1: Run full memory test suite**
1113
+
1114
+ Run: `pnpm test -- src/memory`
1115
+ Expected: All tests pass (baseline + new tests)
1116
+
1117
+ **Step 2: Run build**
1118
+
1119
+ Run: `pnpm build`
1120
+ Expected: Exit 0
1121
+
1122
+ **Step 3: Run lint/format**
1123
+
1124
+ Run: `pnpm check`
1125
+ Expected: Clean (or baseline-only issues)
1126
+
1127
+ **Step 4: Run e2e tests (if MONGODB_TEST_URI available)**
1128
+
1129
+ Run: `MONGODB_TEST_URI=... pnpm test -- --config vitest.e2e.config.ts src/memory/mongodb-e2e.e2e.test.ts`
1130
+ Expected: All scenarios pass
1131
+
1132
+ **Step 5: Final commit if any cleanup needed**
1133
+
1134
+ ---
1135
+
1136
+ ## Risks And Mitigations
1137
+
1138
+ | Risk | P | I | Score | Mitigation |
1139
+ | ------------------------------------------------------- | --- | --- | ----- | -------------------------------------------------------------------------------------- |
1140
+ | RRF normalization changes result ordering | 3 | 3 | 9 | Existing heuristic reranker + cross-encoder reranker run AFTER RRF, preserving quality |
1141
+ | `$percentile` mock complexity | 1 | 2 | 2 | atlas-local:preview always has latest MongoDB with $percentile; mock in unit tests |
1142
+ | bulkWrite partial failure | 2 | 3 | 6 | `ordered: false` continues on error; log failures from BulkWriteError |
1143
+ | Removing synonym expansions reduces recall | 2 | 2 | 4 | Only removing cross-domain (api->route); keeping domain-specific |
1144
+ | Profile $lookup split changes entity count due to dedup | 2 | 2 | 4 | Test for functional equivalence; relations with same entity on both sides are rare |
1145
+
1146
+ ## Acceptance Checks
1147
+
1148
+ - `pnpm test -- src/memory` — all tests pass
1149
+ - `pnpm build` — exit 0
1150
+ - `pnpm check` — clean (or baseline-only)
1151
+ - Each CRITICAL fix has at least 2 unit tests
1152
+ - Each HIGH fix has at least 1 unit test
1153
+ - Score normalization produces scores in [0, 1] range
1154
+ - Reranker fetch aborts within 10 seconds on timeout
1155
+ - Entity upserts use bulkWrite (verify via spy or mock)
1156
+ - `entity-extraction` telemetry is emitted
1157
+
1158
+ ## Summary
1159
+
1160
+ - Plan saved: `docs/plans/2026-03-23-supermemory-audit-fixes-plan.md`
1161
+ - Phases: 5
1162
+ - Risks: 5 identified
1163
+ - Key decisions: Manual RRF for score normalization, bulkWrite for entity batching, $percentile for server-side stats, throw on unimplemented query rewrite methods
1164
+
1165
+ ## Recommended Skills for BUILD (SKILL_HINTS for Router)
1166
+
1167
+ - `cc10x:architecture-patterns` (multi-file schema/integration work)
1168
+
1169
+ ## Confidence Score: 88/100
1170
+
1171
+ - Context References included with file:line (+25)
1172
+ - All edge cases documented (+20)
1173
+ - Test commands specific (+20)
1174
+ - Risk mitigations defined (+20)
1175
+ - File paths exact (+15)
1176
+ - Minor uncertainty: mock complexity for RRF normalization tests (-6), profile test setup for split $lookup (-6)
1177
+
1178
+ **Key Assumptions:**
1179
+
1180
+ - atlas-local:preview always ships latest MongoDB — all features ($percentile, $scoreFusion, etc.) are available
1181
+ - `AbortSignal.timeout()` available in Node 22+ runtime (confirmed: Node 18+)
1182
+ - Existing `rrfScore()` function from `mongodb-hybrid.ts` is correct and reusable
1183
+ - bulkWrite `ordered: false` is safe because entity/relation upserts are independent
1184
+
1185
+ ## Findings
1186
+
1187
+ - `mongodb-hybrid.ts` already has RRF scoring, normalization utilities, and OR-join FTS — well-positioned for searchV2 integration
1188
+ - `getEventsByTimeRange` already has a `limit` parameter (default 1000) — M2 fix is trivial
1189
+ - `LLMEntityExtractor` class is well-structured with timeout + fallback — the dead code is only the config-to-instance bridge in `backend-config.ts`
1190
+ - Profile synthesis `$lookup` with `$or` is the only non-indexed aggregation in the supermemory subsystem
1191
+
1192
+ ## Task Status
1193
+
1194
+ - Follow-up tasks created: None
1195
+ - **CRITICAL:** Now execute the `TaskUpdate` tool to mark task as completed.
1196
+
1197
+ ## Router Contract (MACHINE-READABLE)
1198
+
1199
+ ```yaml
1200
+ STATUS: PLAN_CREATED
1201
+ PLAN_MODE: execution_plan
1202
+ VERIFICATION_RIGOR: standard
1203
+ CONFIDENCE: 88
1204
+ PLAN_FILE: "docs/plans/2026-03-23-supermemory-audit-fixes-plan.md"
1205
+ PHASES: 5
1206
+ RISKS_IDENTIFIED: 5
1207
+ SCENARIOS:
1208
+ - name: "Reranker fetch timeout"
1209
+ given: "Voyage API is unresponsive"
1210
+ when: "crossEncoderRerank is called"
1211
+ then: "Returns fallback results within 10s, emits ok:false telemetry"
1212
+ - name: "RRF score normalization"
1213
+ given: "searchV2 returns results from vector (0-1), graph (synthetic), and episode (synthetic) paths"
1214
+ when: "Results are merged and deduplicated"
1215
+ then: "All final scores are RRF-normalized in [0,1] range, sorted by fused RRF score"
1216
+ - name: "bulkWrite entity upserts"
1217
+ given: "extractAndUpsertEntities receives content with 5 entities"
1218
+ when: "Entities and relations are persisted"
1219
+ then: "One bulkWrite call for entities, one for relations, one for links (3 round-trips, not 25)"
1220
+ - name: "Empty snippet filtering"
1221
+ given: "Reranker receives results with empty graph snippets"
1222
+ when: "Candidates are prepared for API call"
1223
+ then: "Empty snippets are excluded from API call and appended after reranked results"
1224
+ - name: "Query rewriter validation"
1225
+ given: "Config sets queryRewriting.method to 'llm'"
1226
+ when: "rewriteQuery is called"
1227
+ then: "Throws Error with clear message about unimplemented method"
1228
+ - name: "Server-side percentile stats"
1229
+ given: "Telemetry collection has 100+ latency documents"
1230
+ when: "getLatencyStats is called"
1231
+ then: "Pipeline uses $percentile aggregation, no client-side array processing"
1232
+ - name: "Cache TTL from paths"
1233
+ given: "searchV2 executed kb path"
1234
+ when: "Cache write fires"
1235
+ then: "TTL uses kbTtlSec, not static config"
1236
+ - name: "Profile $lookup indexed"
1237
+ given: "Entity has relations via both fromEntityId and toEntityId"
1238
+ when: "synthesizeProfile is called"
1239
+ then: "Two separate indexed $eq lookups are used instead of $or in $expr"
1240
+ ASSUMPTIONS:
1241
+ [
1242
+ "atlas-local 8.2 supports $percentile",
1243
+ "AbortSignal.timeout available in Node 22+",
1244
+ "rrfScore from mongodb-hybrid.ts is correct",
1245
+ "bulkWrite ordered:false safe for independent upserts",
1246
+ ]
1247
+ DECISIONS:
1248
+ [
1249
+ "Manual RRF for cross-path score normalization",
1250
+ "bulkWrite for entity batching",
1251
+ "$percentile for server-side stats",
1252
+ "Throw on unimplemented query rewrite methods",
1253
+ "Remove cross-domain synonym expansions",
1254
+ ]
1255
+ OPEN_DECISIONS: []
1256
+ DIFFERENCES_FROM_AGREEMENT: []
1257
+ RECOMMENDED_DEFAULTS:
1258
+ ["RRF k=60", "Rerank timeout 10s", "Raw-window limit 50", "Synonym max ratio 3x"]
1259
+ ALTERNATIVES: ["Min-max normalization instead of RRF", "Transactions instead of bulkWrite"]
1260
+ DRAWBACKS:
1261
+ [
1262
+ "RRF discards score magnitude information",
1263
+ "$percentile is approximate",
1264
+ "Removing synonym expansions may reduce recall",
1265
+ ]
1266
+ PROVABLE_PROPERTIES: []
1267
+ BLOCKING: false
1268
+ NEXT_ACTION: "build"
1269
+ REMEDIATION_NEEDED: false
1270
+ REQUIRES_REMEDIATION: false
1271
+ REMEDIATION_REASON: null
1272
+ GATE_PASSED: true
1273
+ USER_INPUT_NEEDED: []
1274
+ MEMORY_NOTES:
1275
+ learnings:
1276
+ [
1277
+ "15 audit fixes planned across 9 source files",
1278
+ "mongodb-hybrid.ts RRF utilities reusable in searchV2",
1279
+ "getEventsByTimeRange already has limit param",
1280
+ "Profile $lookup with $or is only non-indexed aggregation",
1281
+ ]
1282
+ patterns:
1283
+ [
1284
+ "Manual RRF for cross-path score normalization",
1285
+ "bulkWrite ordered:false for independent entity upserts",
1286
+ "$percentile GA since MongoDB 7.0",
1287
+ "AbortSignal.timeout for external API calls",
1288
+ ]
1289
+ verification:
1290
+ ["Plan: docs/plans/2026-03-23-supermemory-audit-fixes-plan.md with 88/100 confidence"]
1291
+ ```