@remnic/core 1.1.12 → 1.1.13

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 (1324) hide show
  1. package/dist/access-cli.d.ts +2 -1
  2. package/dist/access-cli.js +263 -82
  3. package/dist/access-cli.js.map +1 -1
  4. package/dist/access-http.d.ts +26 -60
  5. package/dist/access-http.js +43 -29
  6. package/dist/access-mcp.d.ts +24 -6
  7. package/dist/access-mcp.js +35 -28
  8. package/dist/access-schema.d.ts +9 -6
  9. package/dist/access-schema.js +7 -5
  10. package/dist/access-service-DcCDmNYC.d.ts +1542 -0
  11. package/dist/access-service.d.ts +25 -7
  12. package/dist/access-service.js +33 -26
  13. package/dist/active-memory-bridge.js +2 -2
  14. package/dist/active-recall.js +11 -3
  15. package/dist/active-recall.js.map +1 -1
  16. package/dist/adapters/claude-code.d.ts +24 -0
  17. package/dist/adapters/claude-code.js +9 -0
  18. package/dist/adapters/codex.d.ts +25 -0
  19. package/dist/adapters/codex.js +9 -0
  20. package/dist/adapters/hermes.d.ts +35 -0
  21. package/dist/adapters/hermes.js +9 -0
  22. package/dist/adapters/index.d.ts +6 -0
  23. package/dist/adapters/index.js +26 -0
  24. package/dist/adapters/registry.d.ts +20 -0
  25. package/dist/adapters/registry.js +13 -0
  26. package/dist/adapters/replit.d.ts +28 -0
  27. package/dist/adapters/replit.js +9 -0
  28. package/dist/adapters/types.d.ts +43 -0
  29. package/dist/adapters/types.js +8 -0
  30. package/dist/bootstrap.d.ts +20 -5
  31. package/dist/boxes.d.ts +7 -0
  32. package/dist/boxes.js +1 -1
  33. package/dist/briefing.d.ts +5 -3
  34. package/dist/briefing.js +9 -6
  35. package/dist/buffer-surprise-report.js +1 -1
  36. package/dist/buffer.d.ts +18 -4
  37. package/dist/buffer.js +1 -1
  38. package/dist/calibration.js +4 -4
  39. package/dist/capsule-cli.d.ts +4 -4
  40. package/dist/capsule-cli.js +1 -1
  41. package/dist/capsule-crypto-5CYAGVC5.js +18 -0
  42. package/dist/capsule-merge-4MGKE7C5.js +189 -0
  43. package/dist/causal-behavior.d.ts +8 -28
  44. package/dist/causal-behavior.js +6 -3
  45. package/dist/causal-behavior.js.map +1 -1
  46. package/dist/causal-chain.js +3 -2
  47. package/dist/causal-consolidation.d.ts +1 -1
  48. package/dist/causal-consolidation.js +24 -13
  49. package/dist/causal-consolidation.js.map +1 -1
  50. package/dist/causal-retrieval.js +3 -3
  51. package/dist/causal-trajectory.js +1 -1
  52. package/dist/chunk-25MQ7IHJ.js +427 -0
  53. package/dist/chunk-25MQ7IHJ.js.map +1 -0
  54. package/dist/chunk-2F2W355T.js +256 -0
  55. package/dist/chunk-2F2W355T.js.map +1 -0
  56. package/dist/chunk-2KI4QFHU.js +228 -0
  57. package/dist/chunk-2KI4QFHU.js.map +1 -0
  58. package/dist/chunk-2PRQG7PV.js +86 -0
  59. package/dist/chunk-2PRQG7PV.js.map +1 -0
  60. package/dist/chunk-2QR3XXIC.js +2272 -0
  61. package/dist/chunk-2QR3XXIC.js.map +1 -0
  62. package/dist/chunk-2WWLHTZY.js +121 -0
  63. package/dist/chunk-326G7DJK.js +2185 -0
  64. package/dist/chunk-326G7DJK.js.map +1 -0
  65. package/dist/chunk-34DQE4KF.js +174 -0
  66. package/dist/chunk-34DQE4KF.js.map +1 -0
  67. package/dist/chunk-3APJ5EVB.js +601 -0
  68. package/dist/chunk-3APJ5EVB.js.map +1 -0
  69. package/dist/chunk-3HPAPHUK.js +51 -0
  70. package/dist/chunk-3HPAPHUK.js.map +1 -0
  71. package/dist/chunk-3JXBXXM2.js +69 -0
  72. package/dist/chunk-3JXBXXM2.js.map +1 -0
  73. package/dist/chunk-3KW65B36.js +681 -0
  74. package/dist/chunk-3KW65B36.js.map +1 -0
  75. package/dist/chunk-3UXOZBHV.js +20 -0
  76. package/dist/chunk-3UXOZBHV.js.map +1 -0
  77. package/dist/chunk-3VAL7ZL2.js +266 -0
  78. package/dist/chunk-3VAL7ZL2.js.map +1 -0
  79. package/dist/chunk-3Y4P7RXM.js +31 -0
  80. package/dist/chunk-3Y4P7RXM.js.map +1 -0
  81. package/dist/chunk-47VWKCAF.js +273 -0
  82. package/dist/chunk-47VWKCAF.js.map +1 -0
  83. package/dist/chunk-4CRG46BG.js +271 -0
  84. package/dist/chunk-5375UYTQ.js +914 -0
  85. package/dist/chunk-5375UYTQ.js.map +1 -0
  86. package/dist/chunk-56K5QLHX.js +506 -0
  87. package/dist/chunk-56K5QLHX.js.map +1 -0
  88. package/dist/chunk-5RGLBDQF.js +596 -0
  89. package/dist/chunk-5RGLBDQF.js.map +1 -0
  90. package/dist/chunk-5UZXUTVO.js +9 -0
  91. package/dist/chunk-5UZXUTVO.js.map +1 -0
  92. package/dist/chunk-65PG43EQ.js +105 -0
  93. package/dist/chunk-65PG43EQ.js.map +1 -0
  94. package/dist/chunk-66DHUKLO.js +57 -0
  95. package/dist/chunk-66DHUKLO.js.map +1 -0
  96. package/dist/chunk-6FC5EGNV.js +46 -0
  97. package/dist/chunk-6FC5EGNV.js.map +1 -0
  98. package/dist/chunk-6H2TESSP.js +62 -0
  99. package/dist/chunk-6H2TESSP.js.map +1 -0
  100. package/dist/chunk-6LVVDPJ4.js +32 -0
  101. package/dist/chunk-6LVVDPJ4.js.map +1 -0
  102. package/dist/chunk-6RVI47ZR.js +159 -0
  103. package/dist/chunk-6RVI47ZR.js.map +1 -0
  104. package/dist/chunk-7AAT6G4Q.js +5117 -0
  105. package/dist/chunk-7AAT6G4Q.js.map +1 -0
  106. package/dist/chunk-7DTASS5T.js +29 -0
  107. package/dist/chunk-7DTASS5T.js.map +1 -0
  108. package/dist/chunk-7IASACLB.js +596 -0
  109. package/dist/chunk-7MNMYOFP.js +32 -0
  110. package/dist/chunk-7MNMYOFP.js.map +1 -0
  111. package/dist/chunk-7N4KAIGN.js +133 -0
  112. package/dist/chunk-7N4KAIGN.js.map +1 -0
  113. package/dist/chunk-7OZ53EXP.js +101 -0
  114. package/dist/chunk-7OZ53EXP.js.map +1 -0
  115. package/dist/chunk-7XYTQGCC.js +134 -0
  116. package/dist/chunk-7XYTQGCC.js.map +1 -0
  117. package/dist/chunk-A2XUIMJ3.js +341 -0
  118. package/dist/chunk-A2XUIMJ3.js.map +1 -0
  119. package/dist/chunk-AGZQD76C.js +201 -0
  120. package/dist/chunk-AGZQD76C.js.map +1 -0
  121. package/dist/chunk-APO3DCMU.js +361 -0
  122. package/dist/chunk-APO3DCMU.js.map +1 -0
  123. package/dist/chunk-BFBF3XEF.js +283 -0
  124. package/dist/chunk-BFBF3XEF.js.map +1 -0
  125. package/dist/chunk-BJ3KMYTB.js +1974 -0
  126. package/dist/chunk-BJ3KMYTB.js.map +1 -0
  127. package/dist/chunk-CHEL3SKB.js +6758 -0
  128. package/dist/chunk-CHEL3SKB.js.map +1 -0
  129. package/dist/chunk-CQZRLNMV.js +1491 -0
  130. package/dist/chunk-CQZRLNMV.js.map +1 -0
  131. package/dist/chunk-D46YSIYX.js +892 -0
  132. package/dist/chunk-D46YSIYX.js.map +1 -0
  133. package/dist/chunk-DINWEURR.js +648 -0
  134. package/dist/chunk-DINWEURR.js.map +1 -0
  135. package/dist/chunk-DK5LDEQM.js +530 -0
  136. package/dist/chunk-DK5LDEQM.js.map +1 -0
  137. package/dist/chunk-DOM4GKSW.js +34 -0
  138. package/dist/chunk-DOM4GKSW.js.map +1 -0
  139. package/dist/chunk-EDTHC6UD.js +1075 -0
  140. package/dist/chunk-EFJ3MQ4V.js +721 -0
  141. package/dist/chunk-EHRTFRWW.js +89 -0
  142. package/dist/chunk-EHRTFRWW.js.map +1 -0
  143. package/dist/chunk-FAJ7FZYM.js +11 -0
  144. package/dist/chunk-FAJ7FZYM.js.map +1 -0
  145. package/dist/chunk-FBYESMQ2.js +570 -0
  146. package/dist/chunk-FDU6HUUL.js +147 -0
  147. package/dist/chunk-FF4KLI5W.js +99 -0
  148. package/dist/chunk-FF4KLI5W.js.map +1 -0
  149. package/dist/chunk-FIT6DMX6.js +310 -0
  150. package/dist/chunk-FIT6DMX6.js.map +1 -0
  151. package/dist/chunk-FJ43PRLT.js +272 -0
  152. package/dist/chunk-FJ43PRLT.js.map +1 -0
  153. package/dist/chunk-FKFMOY3N.js +32 -0
  154. package/dist/chunk-FKFMOY3N.js.map +1 -0
  155. package/dist/chunk-FLTNHQK6.js +262 -0
  156. package/dist/chunk-FLTNHQK6.js.map +1 -0
  157. package/dist/chunk-GA454ALV.js +12436 -0
  158. package/dist/chunk-GA454ALV.js.map +1 -0
  159. package/dist/chunk-GGKRUQOO.js +228 -0
  160. package/dist/chunk-GIF42EW3.js +63 -0
  161. package/dist/chunk-GIF42EW3.js.map +1 -0
  162. package/dist/chunk-GL6I6MEQ.js +647 -0
  163. package/dist/chunk-H3ME6L6D.js +709 -0
  164. package/dist/chunk-H3ME6L6D.js.map +1 -0
  165. package/dist/chunk-HHLLAQGZ.js +1 -0
  166. package/dist/chunk-HXXBL2KD.js +2040 -0
  167. package/dist/chunk-I5V2VDIW.js +219 -0
  168. package/dist/chunk-I5V2VDIW.js.map +1 -0
  169. package/dist/chunk-I6K5FBRQ.js +35 -0
  170. package/dist/chunk-I6K5FBRQ.js.map +1 -0
  171. package/dist/chunk-ICRIXAP2.js +121 -0
  172. package/dist/chunk-ICRIXAP2.js.map +1 -0
  173. package/dist/chunk-J4EB7DNW.js +11 -0
  174. package/dist/chunk-J4EB7DNW.js.map +1 -0
  175. package/dist/chunk-JLFA7DQG.js +62 -0
  176. package/dist/chunk-JLFA7DQG.js.map +1 -0
  177. package/dist/chunk-KJTKLXTH.js +9 -0
  178. package/dist/chunk-KJTKLXTH.js.map +1 -0
  179. package/dist/chunk-KLAO5DGL.js +917 -0
  180. package/dist/chunk-KLAO5DGL.js.map +1 -0
  181. package/dist/chunk-KNKUID7G.js +183 -0
  182. package/dist/chunk-KOSORCJG.js +624 -0
  183. package/dist/chunk-KOSORCJG.js.map +1 -0
  184. package/dist/chunk-KUJVMMZQ.js +1262 -0
  185. package/dist/chunk-KUJVMMZQ.js.map +1 -0
  186. package/dist/chunk-LCR46JY5.js +123 -0
  187. package/dist/chunk-LCR46JY5.js.map +1 -0
  188. package/dist/chunk-LLQ2LLWF.js +148 -0
  189. package/dist/chunk-LLQ2LLWF.js.map +1 -0
  190. package/dist/chunk-LPMVBPA3.js +236 -0
  191. package/dist/chunk-LT3NLYSI.js +50 -0
  192. package/dist/chunk-LT3NLYSI.js.map +1 -0
  193. package/dist/chunk-LUDTDZLK.js +287 -0
  194. package/dist/chunk-LUDTDZLK.js.map +1 -0
  195. package/dist/chunk-M23FSH32.js +3963 -0
  196. package/dist/chunk-M23FSH32.js.map +1 -0
  197. package/dist/chunk-MC26UJIM.js +118 -0
  198. package/dist/chunk-ME6ESPZU.js +119 -0
  199. package/dist/chunk-ME6ESPZU.js.map +1 -0
  200. package/dist/chunk-MGKYQQYF.js +272 -0
  201. package/dist/chunk-MJFNCJXV.js +66 -0
  202. package/dist/chunk-MJFNCJXV.js.map +1 -0
  203. package/dist/chunk-MSWG7JI6.js +237 -0
  204. package/dist/chunk-MSWG7JI6.js.map +1 -0
  205. package/dist/chunk-MT25YHYH.js +141 -0
  206. package/dist/chunk-MT25YHYH.js.map +1 -0
  207. package/dist/chunk-MT4HVDUZ.js +53 -0
  208. package/dist/chunk-MY6TPVXW.js +219 -0
  209. package/dist/chunk-N2D6GXBM.js +267 -0
  210. package/dist/chunk-N2D6GXBM.js.map +1 -0
  211. package/dist/chunk-NJ3MJQZX.js +46 -0
  212. package/dist/chunk-NJ3MJQZX.js.map +1 -0
  213. package/dist/chunk-NMZY542O.js +335 -0
  214. package/dist/chunk-NMZY542O.js.map +1 -0
  215. package/dist/chunk-NNVTUXEB.js +23 -0
  216. package/dist/chunk-NZL6GGQE.js +375 -0
  217. package/dist/chunk-NZL6GGQE.js.map +1 -0
  218. package/dist/chunk-P4NEIHUT.js +108 -0
  219. package/dist/chunk-P7FMDTKL.js +103 -0
  220. package/dist/chunk-P7FMDTKL.js.map +1 -0
  221. package/dist/chunk-PHK3HARR.js +32 -0
  222. package/dist/chunk-PHK3HARR.js.map +1 -0
  223. package/dist/chunk-PIRJPV5T.js +98 -0
  224. package/dist/chunk-PIRJPV5T.js.map +1 -0
  225. package/dist/chunk-PK7H5L6Y.js +159 -0
  226. package/dist/chunk-PK7H5L6Y.js.map +1 -0
  227. package/dist/chunk-PR5FBTFU.js +233 -0
  228. package/dist/chunk-PR5FBTFU.js.map +1 -0
  229. package/dist/chunk-PU63GXWS.js +174 -0
  230. package/dist/chunk-PU63GXWS.js.map +1 -0
  231. package/dist/chunk-PZIAX57I.js +124 -0
  232. package/dist/chunk-PZIAX57I.js.map +1 -0
  233. package/dist/chunk-Q7P4WJDP.js +26 -0
  234. package/dist/chunk-Q7P4WJDP.js.map +1 -0
  235. package/dist/chunk-QQUAB63I.js +63 -0
  236. package/dist/chunk-QQUAB63I.js.map +1 -0
  237. package/dist/chunk-QRNI5JBH.js +18 -0
  238. package/dist/chunk-RHY3HH7P.js +601 -0
  239. package/dist/chunk-RHY3HH7P.js.map +1 -0
  240. package/dist/chunk-RRF5UOBJ.js +91 -0
  241. package/dist/chunk-RXDLTSWT.js +124 -0
  242. package/dist/chunk-RXDLTSWT.js.map +1 -0
  243. package/dist/chunk-RYED3SPJ.js +42 -0
  244. package/dist/chunk-RYED3SPJ.js.map +1 -0
  245. package/dist/chunk-S7KDBTWT.js +106 -0
  246. package/dist/chunk-S7KDBTWT.js.map +1 -0
  247. package/dist/chunk-SEDEKFYQ.js +1 -0
  248. package/dist/chunk-TECVW3JP.js +36 -0
  249. package/dist/chunk-TECVW3JP.js.map +1 -0
  250. package/dist/chunk-TFO23QT4.js +88 -0
  251. package/dist/chunk-TFO23QT4.js.map +1 -0
  252. package/dist/chunk-TK4UEOSK.js +76 -0
  253. package/dist/chunk-TK4UEOSK.js.map +1 -0
  254. package/dist/chunk-TKWGAOLV.js +122 -0
  255. package/dist/chunk-TKWGAOLV.js.map +1 -0
  256. package/dist/chunk-TMM4S4IJ.js +597 -0
  257. package/dist/chunk-TMM4S4IJ.js.map +1 -0
  258. package/dist/chunk-TMQLARTH.js +188 -0
  259. package/dist/chunk-TMQLARTH.js.map +1 -0
  260. package/dist/chunk-TPDBFYEG.js +130 -0
  261. package/dist/chunk-TPDBFYEG.js.map +1 -0
  262. package/dist/chunk-TPMQ3G6Z.js +145 -0
  263. package/dist/chunk-TPMQ3G6Z.js.map +1 -0
  264. package/dist/chunk-TZOLIGIG.js +61 -0
  265. package/dist/chunk-TZOLIGIG.js.map +1 -0
  266. package/dist/chunk-U3PN77QT.js +113 -0
  267. package/dist/chunk-U3WSW6PZ.js +277 -0
  268. package/dist/chunk-U4SCL7B7.js +640 -0
  269. package/dist/chunk-U4SCL7B7.js.map +1 -0
  270. package/dist/chunk-UWK5OXUJ.js +156 -0
  271. package/dist/chunk-UWK5OXUJ.js.map +1 -0
  272. package/dist/chunk-UWVJF25J.js +74 -0
  273. package/dist/chunk-UXHQAFNA.js +1317 -0
  274. package/dist/chunk-UXHQAFNA.js.map +1 -0
  275. package/dist/chunk-V5OCT34X.js +1 -0
  276. package/dist/chunk-VLXA6PI2.js +304 -0
  277. package/dist/chunk-VLXA6PI2.js.map +1 -0
  278. package/dist/chunk-VNO6ZJ35.js +500 -0
  279. package/dist/chunk-VNO6ZJ35.js.map +1 -0
  280. package/dist/chunk-VW676BEI.js +827 -0
  281. package/dist/chunk-VW676BEI.js.map +1 -0
  282. package/dist/chunk-W3LR522O.js +2296 -0
  283. package/dist/chunk-W4L6CZKA.js +96 -0
  284. package/dist/chunk-W4L6CZKA.js.map +1 -0
  285. package/dist/chunk-W4RVMTHR.js +372 -0
  286. package/dist/chunk-W4RVMTHR.js.map +1 -0
  287. package/dist/chunk-WEHSQBFR.js +188 -0
  288. package/dist/chunk-WEHSQBFR.js.map +1 -0
  289. package/dist/chunk-WELDCG6C.js +380 -0
  290. package/dist/chunk-WELDCG6C.js.map +1 -0
  291. package/dist/chunk-WZYKANL3.js +2800 -0
  292. package/dist/chunk-WZYKANL3.js.map +1 -0
  293. package/dist/chunk-XIG5PDM7.js +48 -0
  294. package/dist/chunk-XJNBEDFE.js +193 -0
  295. package/dist/chunk-XJNBEDFE.js.map +1 -0
  296. package/dist/chunk-XVVIG67A.js +291 -0
  297. package/dist/chunk-XVVIG67A.js.map +1 -0
  298. package/dist/chunk-XVZ7B3HG.js +135 -0
  299. package/dist/chunk-YBPYIAA5.js +73 -0
  300. package/dist/chunk-YBPYIAA5.js.map +1 -0
  301. package/dist/chunk-Z734BLO3.js +21 -0
  302. package/dist/chunk-Z734BLO3.js.map +1 -0
  303. package/dist/chunk-ZKSK55RC.js +269 -0
  304. package/dist/chunk-ZKSK55RC.js.map +1 -0
  305. package/dist/chunk-ZTFCYYEZ.js +69 -0
  306. package/dist/chunk-ZTFCYYEZ.js.map +1 -0
  307. package/dist/chunk-ZY2MNJR6.js +329 -0
  308. package/dist/chunk-ZY2MNJR6.js.map +1 -0
  309. package/dist/cli-D3VpkVwB.d.ts +1136 -0
  310. package/dist/cli.d.ts +39 -10
  311. package/dist/cli.js +108 -49
  312. package/dist/commitment-ledger.js +1 -1
  313. package/dist/compat/checks.d.ts +5 -0
  314. package/dist/compat/checks.js +11 -0
  315. package/dist/compat/checks.js.map +1 -0
  316. package/dist/compat/types.d.ts +30 -0
  317. package/dist/compat/types.js +1 -0
  318. package/dist/compat/types.js.map +1 -0
  319. package/dist/compounding/engine.d.ts +221 -0
  320. package/dist/compounding/engine.js +32 -0
  321. package/dist/compounding/engine.js.map +1 -0
  322. package/dist/compounding/preference-consolidator.d.ts +92 -0
  323. package/dist/compounding/preference-consolidator.js +553 -0
  324. package/dist/compounding/preference-consolidator.js.map +1 -0
  325. package/dist/config.d.ts +4 -2
  326. package/dist/config.js +9 -4
  327. package/dist/conflict-policy-DyJ2wd-h.d.ts +4 -0
  328. package/dist/connectors/codex-materialize-runner.d.ts +64 -0
  329. package/dist/connectors/codex-materialize-runner.js +33 -0
  330. package/dist/connectors/codex-materialize-runner.js.map +1 -0
  331. package/dist/connectors/codex-materialize.d.ts +195 -0
  332. package/dist/connectors/codex-materialize.js +38 -0
  333. package/dist/connectors/codex-materialize.js.map +1 -0
  334. package/dist/connectors/index.d.ts +444 -0
  335. package/dist/connectors/index.js +115 -0
  336. package/dist/connectors/index.js.map +1 -0
  337. package/dist/connectors-cli-CwbyjGR7.d.ts +257 -0
  338. package/dist/connectors-cli.d.ts +1 -1
  339. package/dist/consolidation-provenance-check.d.ts +3 -1
  340. package/dist/consolidation-undo.d.ts +3 -1
  341. package/dist/contradiction/index.d.ts +258 -0
  342. package/dist/contradiction/index.js +43 -0
  343. package/dist/contradiction/index.js.map +1 -0
  344. package/dist/contradiction-review-ATP4S6IC.js +30 -0
  345. package/dist/contradiction-review-ATP4S6IC.js.map +1 -0
  346. package/dist/contradiction-scan-5A4IDZV5.js +13 -0
  347. package/dist/contradiction-scan-5A4IDZV5.js.map +1 -0
  348. package/dist/conversation-index/backend.d.ts +97 -0
  349. package/dist/conversation-index/backend.js +13 -0
  350. package/dist/conversation-index/backend.js.map +1 -0
  351. package/dist/conversation-index/chunker.d.ts +16 -0
  352. package/dist/conversation-index/chunker.js +8 -0
  353. package/dist/conversation-index/chunker.js.map +1 -0
  354. package/dist/conversation-index/cleanup.d.ts +11 -0
  355. package/dist/conversation-index/cleanup.js +9 -0
  356. package/dist/conversation-index/cleanup.js.map +1 -0
  357. package/dist/conversation-index/faiss-adapter.d.ts +6 -0
  358. package/dist/conversation-index/faiss-adapter.js +16 -0
  359. package/dist/conversation-index/faiss-adapter.js.map +1 -0
  360. package/dist/conversation-index/indexer.d.ts +23 -0
  361. package/dist/conversation-index/indexer.js +15 -0
  362. package/dist/conversation-index/indexer.js.map +1 -0
  363. package/dist/conversation-index/search.d.ts +6 -0
  364. package/dist/conversation-index/search.js +11 -0
  365. package/dist/conversation-index/search.js.map +1 -0
  366. package/dist/embedding-fallback.js +2 -2
  367. package/dist/enrichment/index.d.ts +163 -0
  368. package/dist/enrichment/index.js +18 -0
  369. package/dist/enrichment/index.js.map +1 -0
  370. package/dist/entity-retrieval.d.ts +4 -2
  371. package/dist/entity-retrieval.js +8 -5
  372. package/dist/evals.js +1 -1
  373. package/dist/explicit-capture.d.ts +20 -5
  374. package/dist/explicit-capture.js +2 -2
  375. package/dist/extraction-judge-training.js +1 -1
  376. package/dist/extraction.js +8 -8
  377. package/dist/faiss-adapter-CzPghc4C.d.ts +70 -0
  378. package/dist/fallback-llm.d.ts +2 -0
  379. package/dist/fallback-llm.js +4 -4
  380. package/dist/graph-edge-decay-5DI5GUNL.js +207 -0
  381. package/dist/index.d.ts +66 -711
  382. package/dist/index.js +556 -2680
  383. package/dist/index.js.map +1 -1
  384. package/dist/lcm/archive.d.ts +89 -0
  385. package/dist/lcm/archive.js +12 -0
  386. package/dist/lcm/archive.js.map +1 -0
  387. package/dist/lcm/dag.d.ts +48 -0
  388. package/dist/lcm/dag.js +8 -0
  389. package/dist/lcm/dag.js.map +1 -0
  390. package/dist/lcm/engine.d.ts +116 -0
  391. package/dist/lcm/engine.js +20 -0
  392. package/dist/lcm/engine.js.map +1 -0
  393. package/dist/lcm/index.d.ts +12 -0
  394. package/dist/lcm/index.js +44 -0
  395. package/dist/lcm/index.js.map +1 -0
  396. package/dist/lcm/queue.d.ts +62 -0
  397. package/dist/lcm/queue.js +8 -0
  398. package/dist/lcm/queue.js.map +1 -0
  399. package/dist/lcm/recall.d.ts +20 -0
  400. package/dist/lcm/recall.js +8 -0
  401. package/dist/lcm/recall.js.map +1 -0
  402. package/dist/lcm/schema.d.ts +16 -0
  403. package/dist/lcm/schema.js +14 -0
  404. package/dist/lcm/schema.js.map +1 -0
  405. package/dist/lcm/summarizer.d.ts +38 -0
  406. package/dist/lcm/summarizer.js +12 -0
  407. package/dist/lcm/summarizer.js.map +1 -0
  408. package/dist/lcm/tools.d.ts +29 -0
  409. package/dist/lcm/tools.js +8 -0
  410. package/dist/lcm/tools.js.map +1 -0
  411. package/dist/live-connectors-runner.js +5 -5
  412. package/dist/local-llm.js +3 -3
  413. package/dist/maintenance/archive-observations.d.ts +18 -0
  414. package/dist/maintenance/archive-observations.js +8 -0
  415. package/dist/maintenance/archive-observations.js.map +1 -0
  416. package/dist/maintenance/backup-stamp.d.ts +3 -0
  417. package/dist/maintenance/backup-stamp.js +8 -0
  418. package/dist/maintenance/backup-stamp.js.map +1 -0
  419. package/dist/maintenance/memory-governance-cron.d.ts +85 -0
  420. package/dist/maintenance/memory-governance-cron.js +22 -0
  421. package/dist/maintenance/memory-governance-cron.js.map +1 -0
  422. package/dist/maintenance/memory-governance.d.ts +137 -0
  423. package/dist/maintenance/memory-governance.js +40 -0
  424. package/dist/maintenance/memory-governance.js.map +1 -0
  425. package/dist/maintenance/migrate-observations.d.ts +18 -0
  426. package/dist/maintenance/migrate-observations.js +9 -0
  427. package/dist/maintenance/migrate-observations.js.map +1 -0
  428. package/dist/maintenance/observation-ledger-utils.d.ts +10 -0
  429. package/dist/maintenance/observation-ledger-utils.js +10 -0
  430. package/dist/maintenance/observation-ledger-utils.js.map +1 -0
  431. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +15 -0
  432. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -0
  433. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js.map +1 -0
  434. package/dist/maintenance/rebuild-memory-projection.d.ts +77 -0
  435. package/dist/maintenance/rebuild-memory-projection.js +35 -0
  436. package/dist/maintenance/rebuild-memory-projection.js.map +1 -0
  437. package/dist/maintenance/rebuild-observations.d.ts +17 -0
  438. package/dist/maintenance/rebuild-observations.js +9 -0
  439. package/dist/maintenance/rebuild-observations.js.map +1 -0
  440. package/dist/mcp-memory-inspector-app.d.ts +24 -6
  441. package/dist/memory-projection-store.d.ts +108 -3
  442. package/dist/memory-projection-store.js +2 -1
  443. package/dist/memory-worth-outcomes.d.ts +4 -2
  444. package/dist/migrate/from-engram.d.ts +24 -0
  445. package/dist/migrate/from-engram.js +12 -0
  446. package/dist/migrate/from-engram.js.map +1 -0
  447. package/dist/namespaces/migrate.d.ts +50 -0
  448. package/dist/namespaces/migrate.js +50 -0
  449. package/dist/namespaces/migrate.js.map +1 -0
  450. package/dist/namespaces/principal.d.ts +17 -0
  451. package/dist/namespaces/principal.js +16 -0
  452. package/dist/namespaces/principal.js.map +1 -0
  453. package/dist/namespaces/search.d.ts +46 -0
  454. package/dist/namespaces/search.js +28 -0
  455. package/dist/namespaces/search.js.map +1 -0
  456. package/dist/namespaces/storage.d.ts +32 -0
  457. package/dist/namespaces/storage.js +28 -0
  458. package/dist/namespaces/storage.js.map +1 -0
  459. package/dist/network/tailscale.d.ts +41 -0
  460. package/dist/network/tailscale.js +9 -0
  461. package/dist/network/tailscale.js.map +1 -0
  462. package/dist/network/webdav.d.ts +39 -0
  463. package/dist/network/webdav.js +10 -0
  464. package/dist/network/webdav.js.map +1 -0
  465. package/dist/objective-state-writers.js +2 -2
  466. package/dist/operator-toolkit.d.ts +4 -2
  467. package/dist/operator-toolkit.js +32 -14
  468. package/dist/opik-exporter.js +2 -2
  469. package/dist/opik-exporter.js.map +1 -1
  470. package/dist/orchestrator-DuWl9Hwx.d.ts +1244 -0
  471. package/dist/orchestrator.d.ts +22 -7
  472. package/dist/orchestrator.js +79 -44
  473. package/dist/path-MR5JPYOP.js +9 -0
  474. package/dist/path-MR5JPYOP.js.map +1 -0
  475. package/dist/qmd-recall-cache.d.ts +1 -1
  476. package/dist/qmd.d.ts +102 -3
  477. package/dist/qmd.js +23 -5
  478. package/dist/recall-explain-renderer.js +3 -3
  479. package/dist/recall-xray-cli.js +4 -4
  480. package/dist/recall-xray-renderer.js +3 -3
  481. package/dist/recall-xray.js +2 -2
  482. package/dist/replay/normalizers/chatgpt.d.ts +6 -0
  483. package/dist/replay/normalizers/chatgpt.js +11 -0
  484. package/dist/replay/normalizers/chatgpt.js.map +1 -0
  485. package/dist/replay/normalizers/claude.d.ts +6 -0
  486. package/dist/replay/normalizers/claude.js +11 -0
  487. package/dist/replay/normalizers/claude.js.map +1 -0
  488. package/dist/replay/normalizers/openclaw.d.ts +6 -0
  489. package/dist/replay/normalizers/openclaw.js +11 -0
  490. package/dist/replay/normalizers/openclaw.js.map +1 -0
  491. package/dist/replay/normalizers/shared.d.ts +16 -0
  492. package/dist/replay/normalizers/shared.js +14 -0
  493. package/dist/replay/normalizers/shared.js.map +1 -0
  494. package/dist/replay/runner.d.ts +35 -0
  495. package/dist/replay/runner.js +16 -0
  496. package/dist/replay/runner.js.map +1 -0
  497. package/dist/replay/types.d.ts +57 -0
  498. package/dist/replay/types.js +19 -0
  499. package/dist/replay/types.js.map +1 -0
  500. package/dist/resolution-B7FNQSSP.js +12 -0
  501. package/dist/resolution-B7FNQSSP.js.map +1 -0
  502. package/dist/resolve-provider-secret.js +2 -2
  503. package/dist/resume-bundles.js +8 -6
  504. package/dist/retrieval-agents.d.ts +1 -1
  505. package/dist/routing/engine.d.ts +35 -0
  506. package/dist/routing/engine.js +16 -0
  507. package/dist/routing/engine.js.map +1 -0
  508. package/dist/routing/store.d.ts +27 -0
  509. package/dist/routing/store.js +10 -0
  510. package/dist/routing/store.js.map +1 -0
  511. package/dist/runtime/better-sqlite.d.ts +8 -0
  512. package/dist/runtime/better-sqlite.js +10 -0
  513. package/dist/runtime/better-sqlite.js.map +1 -0
  514. package/dist/runtime/child-process.d.ts +32 -0
  515. package/dist/runtime/child-process.js +10 -0
  516. package/dist/runtime/child-process.js.map +1 -0
  517. package/dist/runtime/env.d.ts +5 -0
  518. package/dist/runtime/env.js +12 -0
  519. package/dist/runtime/env.js.map +1 -0
  520. package/dist/schemas.d.ts +22 -22
  521. package/dist/sdk-compat.js +1 -1
  522. package/dist/search/document-scanner.d.ts +22 -0
  523. package/dist/search/document-scanner.js +8 -0
  524. package/dist/search/document-scanner.js.map +1 -0
  525. package/dist/search/embed-helper.d.ts +35 -0
  526. package/dist/search/embed-helper.js +9 -0
  527. package/dist/search/embed-helper.js.map +1 -0
  528. package/dist/search/factory.d.ts +32 -0
  529. package/dist/search/factory.js +29 -0
  530. package/dist/search/factory.js.map +1 -0
  531. package/dist/search/index.d.ts +15 -0
  532. package/dist/search/index.js +50 -0
  533. package/dist/search/index.js.map +1 -0
  534. package/dist/search/lancedb-backend.d.ts +51 -0
  535. package/dist/search/lancedb-backend.js +10 -0
  536. package/dist/search/lancedb-backend.js.map +1 -0
  537. package/dist/search/meilisearch-backend.d.ts +48 -0
  538. package/dist/search/meilisearch-backend.js +10 -0
  539. package/dist/search/meilisearch-backend.js.map +1 -0
  540. package/dist/search/noop-backend.d.ts +26 -0
  541. package/dist/search/noop-backend.js +8 -0
  542. package/dist/search/noop-backend.js.map +1 -0
  543. package/dist/search/orama-backend.d.ts +53 -0
  544. package/dist/search/orama-backend.js +10 -0
  545. package/dist/search/orama-backend.js.map +1 -0
  546. package/dist/search/port.d.ts +61 -0
  547. package/dist/search/port.js +1 -0
  548. package/dist/search/port.js.map +1 -0
  549. package/dist/search/remote-backend.d.ts +39 -0
  550. package/dist/search/remote-backend.js +9 -0
  551. package/dist/search/remote-backend.js.map +1 -0
  552. package/dist/secure-store/index.d.ts +890 -0
  553. package/dist/secure-store/index.js +156 -0
  554. package/dist/secure-store/index.js.map +1 -0
  555. package/dist/semantic-VwGI14Ok.d.ts +69 -0
  556. package/dist/semantic-consolidation-4HkHWgeI.d.ts +180 -0
  557. package/dist/semantic-consolidation.d.ts +2 -2
  558. package/dist/semantic-consolidation.js +13 -6
  559. package/dist/semantic-rule-promotion.js +8 -5
  560. package/dist/semantic-rule-verifier.js +8 -5
  561. package/dist/shared-context/manager.d.ts +131 -0
  562. package/dist/shared-context/manager.js +15 -0
  563. package/dist/shared-context/manager.js.map +1 -0
  564. package/dist/skills-registry.js +13 -1
  565. package/dist/skills-registry.js.map +1 -1
  566. package/dist/state-store-VZU2IA53.js +16 -0
  567. package/dist/state-store-VZU2IA53.js.map +1 -0
  568. package/dist/storage-paths.d.ts +9 -0
  569. package/dist/storage-paths.js +20 -0
  570. package/dist/storage-paths.js.map +1 -0
  571. package/dist/storage.d.ts +3 -1
  572. package/dist/storage.js +7 -4
  573. package/dist/summarizer.d.ts +5 -0
  574. package/dist/summarizer.js +9 -8
  575. package/dist/summary-snapshot.js +2 -1
  576. package/dist/surfaces/dreams.d.ts +16 -0
  577. package/dist/surfaces/dreams.js +282 -0
  578. package/dist/surfaces/dreams.js.map +1 -0
  579. package/dist/surfaces/heartbeat.d.ts +17 -0
  580. package/dist/surfaces/heartbeat.js +265 -0
  581. package/dist/surfaces/heartbeat.js.map +1 -0
  582. package/dist/temporal-supersession.d.ts +3 -1
  583. package/dist/threading.d.ts +5 -0
  584. package/dist/threading.js +2 -1
  585. package/dist/tier-migration.d.ts +4 -2
  586. package/dist/tokens.js +2 -2
  587. package/dist/transcript.d.ts +15 -1
  588. package/dist/transcript.js +2 -1
  589. package/dist/transfer/autodetect.d.ts +4 -0
  590. package/dist/transfer/autodetect.js +15 -0
  591. package/dist/transfer/autodetect.js.map +1 -0
  592. package/dist/transfer/backup.d.ts +21 -0
  593. package/dist/transfer/backup.js +17 -0
  594. package/dist/transfer/backup.js.map +1 -0
  595. package/dist/transfer/capsule-export.d.ts +113 -0
  596. package/dist/transfer/capsule-export.js +19 -0
  597. package/dist/transfer/capsule-export.js.map +1 -0
  598. package/dist/transfer/capsule-import.d.ts +124 -0
  599. package/dist/transfer/capsule-import.js +16 -0
  600. package/dist/transfer/capsule-import.js.map +1 -0
  601. package/dist/transfer/constants.d.ts +13 -0
  602. package/dist/transfer/constants.js +12 -0
  603. package/dist/transfer/constants.js.map +1 -0
  604. package/dist/transfer/export-json.d.ts +11 -0
  605. package/dist/transfer/export-json.js +11 -0
  606. package/dist/transfer/export-json.js.map +1 -0
  607. package/dist/transfer/export-md.d.ts +10 -0
  608. package/dist/transfer/export-md.js +13 -0
  609. package/dist/transfer/export-md.js.map +1 -0
  610. package/dist/transfer/export-sqlite.d.ts +9 -0
  611. package/dist/transfer/export-sqlite.js +12 -0
  612. package/dist/transfer/export-sqlite.js.map +1 -0
  613. package/dist/transfer/fs-utils.d.ts +61 -0
  614. package/dist/transfer/fs-utils.js +40 -0
  615. package/dist/transfer/fs-utils.js.map +1 -0
  616. package/dist/transfer/import-json.d.ts +16 -0
  617. package/dist/transfer/import-json.js +13 -0
  618. package/dist/transfer/import-json.js.map +1 -0
  619. package/dist/transfer/import-md.d.ts +14 -0
  620. package/dist/transfer/import-md.js +11 -0
  621. package/dist/transfer/import-md.js.map +1 -0
  622. package/dist/transfer/import-sqlite.d.ts +14 -0
  623. package/dist/transfer/import-sqlite.js +12 -0
  624. package/dist/transfer/import-sqlite.js.map +1 -0
  625. package/dist/transfer/sqlite-schema.d.ts +4 -0
  626. package/dist/transfer/sqlite-schema.js +10 -0
  627. package/dist/transfer/sqlite-schema.js.map +1 -0
  628. package/dist/transfer/types.d.ts +916 -0
  629. package/dist/transfer/types.js +30 -0
  630. package/dist/transfer/types.js.map +1 -0
  631. package/dist/types.d.ts +28 -1
  632. package/dist/types.js +1 -1
  633. package/dist/verified-recall.js +9 -6
  634. package/dist/work/board.d.ts +43 -0
  635. package/dist/work/board.js +14 -0
  636. package/dist/work/board.js.map +1 -0
  637. package/dist/work/boundary.d.ts +8 -0
  638. package/dist/work/boundary.js +14 -0
  639. package/dist/work/boundary.js.map +1 -0
  640. package/dist/work/storage.d.ts +39 -0
  641. package/dist/work/storage.js +11 -0
  642. package/dist/work/storage.js.map +1 -0
  643. package/dist/work/types.d.ts +75 -0
  644. package/dist/work/types.js +1 -0
  645. package/dist/work/types.js.map +1 -0
  646. package/package.json +2767 -6
  647. package/scripts/faiss_index.py +816 -0
  648. package/scripts/faiss_requirements.txt +3 -0
  649. package/skills/remnic-entities/SKILL.md +51 -0
  650. package/skills/remnic-memory-workflow/SKILL.md +61 -0
  651. package/skills/remnic-recall/SKILL.md +51 -0
  652. package/skills/remnic-remember/SKILL.md +56 -0
  653. package/skills/remnic-search/SKILL.md +51 -0
  654. package/skills/remnic-status/SKILL.md +51 -0
  655. package/src/abort-error.test.ts +49 -0
  656. package/src/abort-error.ts +46 -0
  657. package/src/abstraction-nodes.ts +162 -0
  658. package/src/access-audit.test.ts +178 -0
  659. package/src/access-audit.ts +125 -0
  660. package/src/access-cli.test.ts +439 -0
  661. package/src/access-cli.ts +438 -0
  662. package/src/access-http.test.ts +225 -0
  663. package/src/access-http.ts +1899 -0
  664. package/src/access-idempotency.ts +232 -0
  665. package/src/access-mcp.test.ts +568 -0
  666. package/src/access-mcp.ts +3056 -0
  667. package/src/access-schema-pi.test.ts +60 -0
  668. package/src/access-schema.ts +522 -0
  669. package/src/access-service-namespace.test.ts +123 -0
  670. package/src/access-service.ts +5629 -0
  671. package/src/action-confidence.test.ts +206 -0
  672. package/src/action-confidence.ts +466 -0
  673. package/src/active-memory-bridge.test.ts +285 -0
  674. package/src/active-memory-bridge.ts +217 -0
  675. package/src/active-recall.test.ts +484 -0
  676. package/src/active-recall.ts +459 -0
  677. package/src/adapters/claude-code.ts +56 -0
  678. package/src/adapters/codex.ts +57 -0
  679. package/src/adapters/hermes.ts +64 -0
  680. package/src/adapters/index.ts +6 -0
  681. package/src/adapters/registry.ts +41 -0
  682. package/src/adapters/replit.ts +55 -0
  683. package/src/adapters/types.ts +51 -0
  684. package/src/behavior-learner.ts +144 -0
  685. package/src/behavior-signals.ts +73 -0
  686. package/src/binary-lifecycle/backend.ts +117 -0
  687. package/src/binary-lifecycle/index.ts +35 -0
  688. package/src/binary-lifecycle/manifest.ts +79 -0
  689. package/src/binary-lifecycle/pipeline.ts +352 -0
  690. package/src/binary-lifecycle/scanner.ts +89 -0
  691. package/src/binary-lifecycle/types.ts +89 -0
  692. package/src/bootstrap.ts +178 -0
  693. package/src/boxes.ts +521 -0
  694. package/src/briefing.test.ts +1535 -0
  695. package/src/briefing.ts +1382 -0
  696. package/src/buffer-session.test.ts +443 -0
  697. package/src/buffer-surprise-report.ts +176 -0
  698. package/src/buffer-surprise-telemetry.test.ts +606 -0
  699. package/src/buffer-surprise-trigger.test.ts +766 -0
  700. package/src/buffer-surprise.test.ts +339 -0
  701. package/src/buffer-surprise.ts +203 -0
  702. package/src/buffer.ts +900 -0
  703. package/src/bulk-import/cli-command.test.ts +204 -0
  704. package/src/bulk-import/index.ts +34 -0
  705. package/src/bulk-import/pipeline.test.ts +445 -0
  706. package/src/bulk-import/pipeline.ts +178 -0
  707. package/src/bulk-import/registry.test.ts +151 -0
  708. package/src/bulk-import/registry.ts +72 -0
  709. package/src/bulk-import/types.test.ts +272 -0
  710. package/src/bulk-import/types.ts +145 -0
  711. package/src/calibration.ts +394 -0
  712. package/src/capsule-cli.test.ts +398 -0
  713. package/src/capsule-cli.ts +565 -0
  714. package/src/causal-behavior.ts +308 -0
  715. package/src/causal-chain.ts +419 -0
  716. package/src/causal-consolidation.ts +370 -0
  717. package/src/causal-retrieval.ts +286 -0
  718. package/src/causal-trajectory-graph.ts +60 -0
  719. package/src/causal-trajectory.ts +303 -0
  720. package/src/chunking.ts +220 -0
  721. package/src/citations.ts +232 -0
  722. package/src/cli.ts +9403 -0
  723. package/src/codex-cli-fallback.ts +162 -0
  724. package/src/codex-thread-key.ts +1 -0
  725. package/src/coding/access-coding-context.test.ts +197 -0
  726. package/src/coding/coding-branch-scope.test.ts +281 -0
  727. package/src/coding/coding-namespace.test.ts +360 -0
  728. package/src/coding/coding-namespace.ts +412 -0
  729. package/src/coding/coding-orchestrator.test.ts +249 -0
  730. package/src/coding/git-context.test.ts +507 -0
  731. package/src/coding/git-context.ts +336 -0
  732. package/src/coding/mcp-set-coding-context.test.ts +174 -0
  733. package/src/coding/review-context.test.ts +316 -0
  734. package/src/coding/review-context.ts +349 -0
  735. package/src/coding/wire-coding-context.test.ts +468 -0
  736. package/src/commitment-ledger.test.ts +78 -0
  737. package/src/commitment-ledger.ts +337 -0
  738. package/src/compat/checks.test.ts +206 -0
  739. package/src/compat/checks.ts +716 -0
  740. package/src/compat/types.ts +33 -0
  741. package/src/compounding/engine.ts +1686 -0
  742. package/src/compounding/preference-consolidator.ts +778 -0
  743. package/src/compression-optimizer.ts +312 -0
  744. package/src/config.test.ts +930 -0
  745. package/src/config.ts +3807 -0
  746. package/src/connectors/codex/instructions.md +160 -0
  747. package/src/connectors/codex/resources/namespace-cheatsheet.md +48 -0
  748. package/src/connectors/codex-marketplace.ts +500 -0
  749. package/src/connectors/codex-materialize-runner.ts +212 -0
  750. package/src/connectors/codex-materialize.ts +983 -0
  751. package/src/connectors/coerce.ts +62 -0
  752. package/src/connectors/index.test.ts +1570 -0
  753. package/src/connectors/index.ts +3222 -0
  754. package/src/connectors/live/framework.ts +164 -0
  755. package/src/connectors/live/github.test.ts +1218 -0
  756. package/src/connectors/live/github.ts +1068 -0
  757. package/src/connectors/live/gmail.test.ts +1706 -0
  758. package/src/connectors/live/gmail.ts +1293 -0
  759. package/src/connectors/live/google-drive.test.ts +696 -0
  760. package/src/connectors/live/google-drive.ts +724 -0
  761. package/src/connectors/live/index.ts +101 -0
  762. package/src/connectors/live/live-connectors.test.ts +689 -0
  763. package/src/connectors/live/notion.test.ts +1109 -0
  764. package/src/connectors/live/notion.ts +978 -0
  765. package/src/connectors/live/registry.ts +103 -0
  766. package/src/connectors/live/state-store.ts +399 -0
  767. package/src/connectors/live/transient-errors.ts +150 -0
  768. package/src/connectors/weclone-installer.test.ts +850 -0
  769. package/src/connectors-cli.ts +513 -0
  770. package/src/console/state.test.ts +224 -0
  771. package/src/console/state.ts +514 -0
  772. package/src/console/trace.test.ts +813 -0
  773. package/src/console/trace.ts +603 -0
  774. package/src/console/tui.test.ts +582 -0
  775. package/src/console/tui.ts +508 -0
  776. package/src/consolidation-operator.ts +182 -0
  777. package/src/consolidation-provenance-check.ts +551 -0
  778. package/src/consolidation-undo.ts +718 -0
  779. package/src/contradiction/contradiction-judge.test.ts +189 -0
  780. package/src/contradiction/contradiction-judge.ts +333 -0
  781. package/src/contradiction/contradiction-review.ts +574 -0
  782. package/src/contradiction/contradiction-scan.ts +504 -0
  783. package/src/contradiction/contradiction.test.ts +2230 -0
  784. package/src/contradiction/index.ts +37 -0
  785. package/src/contradiction/resolution.ts +383 -0
  786. package/src/conversation-index/backend.ts +323 -0
  787. package/src/conversation-index/chunker.ts +47 -0
  788. package/src/conversation-index/cleanup.ts +53 -0
  789. package/src/conversation-index/faiss-adapter.ts +384 -0
  790. package/src/conversation-index/indexer.test.ts +164 -0
  791. package/src/conversation-index/indexer.ts +192 -0
  792. package/src/conversation-index/search.ts +37 -0
  793. package/src/cross-namespace-budget.test.ts +275 -0
  794. package/src/cross-namespace-budget.ts +365 -0
  795. package/src/cue-anchors.ts +163 -0
  796. package/src/curation/index.ts +544 -0
  797. package/src/dashboard-runtime.ts +337 -0
  798. package/src/day-summary.ts +122 -0
  799. package/src/dedup/index.ts +330 -0
  800. package/src/dedup/semantic.test.ts +1577 -0
  801. package/src/dedup/semantic.ts +148 -0
  802. package/src/delinearize.ts +193 -0
  803. package/src/direct-answer-wiring.test.ts +473 -0
  804. package/src/direct-answer-wiring.ts +180 -0
  805. package/src/direct-answer.test.ts +484 -0
  806. package/src/direct-answer.ts +273 -0
  807. package/src/embedding-fallback.ts +565 -0
  808. package/src/enrichment/audit.ts +89 -0
  809. package/src/enrichment/index.ts +27 -0
  810. package/src/enrichment/pipeline.ts +197 -0
  811. package/src/enrichment/provider-registry.ts +85 -0
  812. package/src/enrichment/types.ts +100 -0
  813. package/src/enrichment/web-search-provider.ts +63 -0
  814. package/src/entity-retrieval.ts +774 -0
  815. package/src/entity-schema.ts +239 -0
  816. package/src/evals.ts +1312 -0
  817. package/src/event-order-recall.test.ts +4164 -0
  818. package/src/event-order-recall.ts +2802 -0
  819. package/src/evidence-pack.test.ts +89 -0
  820. package/src/evidence-pack.ts +388 -0
  821. package/src/explicit-capture.ts +530 -0
  822. package/src/explicit-cue-recall.test.ts +3019 -0
  823. package/src/explicit-cue-recall.ts +5545 -0
  824. package/src/extraction-judge-telemetry.ts +234 -0
  825. package/src/extraction-judge-training.ts +221 -0
  826. package/src/extraction-judge.ts +846 -0
  827. package/src/extraction-timeout.test.ts +265 -0
  828. package/src/extraction.ts +2719 -0
  829. package/src/fallback-llm.test.ts +1060 -0
  830. package/src/fallback-llm.ts +918 -0
  831. package/src/focused-list-recall.test.ts +734 -0
  832. package/src/focused-list-recall.ts +1160 -0
  833. package/src/graph-dashboard-diff.ts +35 -0
  834. package/src/graph-dashboard-key.ts +5 -0
  835. package/src/graph-dashboard-parser.ts +104 -0
  836. package/src/graph-edge-reinforcement.ts +192 -0
  837. package/src/graph-events.ts +151 -0
  838. package/src/graph-recall.test.ts +164 -0
  839. package/src/graph-recall.ts +189 -0
  840. package/src/graph-retrieval.test.ts +809 -0
  841. package/src/graph-retrieval.ts +823 -0
  842. package/src/graph-snapshot.ts +329 -0
  843. package/src/graph.ts +813 -0
  844. package/src/harmonic-retrieval.ts +223 -0
  845. package/src/himem.ts +154 -0
  846. package/src/hygiene.ts +87 -0
  847. package/src/identity-continuity.ts +333 -0
  848. package/src/importance.ts +328 -0
  849. package/src/importers/base.test.ts +294 -0
  850. package/src/importers/base.ts +436 -0
  851. package/src/importers/index.ts +21 -0
  852. package/src/index.ts +1204 -0
  853. package/src/intent.ts +154 -0
  854. package/src/json-extract.ts +85 -0
  855. package/src/json-store.ts +42 -0
  856. package/src/lcm/archive.ts +617 -0
  857. package/src/lcm/dag.ts +199 -0
  858. package/src/lcm/engine.ts +645 -0
  859. package/src/lcm/index.ts +7 -0
  860. package/src/lcm/queue.test.ts +178 -0
  861. package/src/lcm/queue.ts +200 -0
  862. package/src/lcm/recall.ts +117 -0
  863. package/src/lcm/schema.ts +154 -0
  864. package/src/lcm/summarizer.ts +235 -0
  865. package/src/lcm/tools.ts +191 -0
  866. package/src/lcm-engine.test.ts +660 -0
  867. package/src/legacy-hook-compat.test.ts +20 -0
  868. package/src/legacy-hook-compat.ts +45 -0
  869. package/src/lifecycle.ts +289 -0
  870. package/src/live-connectors-runner.ts +385 -0
  871. package/src/local-llm-qos.test.ts +303 -0
  872. package/src/local-llm-thinking.test.ts +292 -0
  873. package/src/local-llm.ts +1464 -0
  874. package/src/logger.ts +49 -0
  875. package/src/maintenance/archive-observations.ts +147 -0
  876. package/src/maintenance/backup-stamp.ts +3 -0
  877. package/src/maintenance/dreams-ledger.ts +516 -0
  878. package/src/maintenance/first-start-migration.ts +362 -0
  879. package/src/maintenance/forget.test.ts +206 -0
  880. package/src/maintenance/forget.ts +126 -0
  881. package/src/maintenance/graph-edge-decay.test.ts +409 -0
  882. package/src/maintenance/graph-edge-decay.ts +394 -0
  883. package/src/maintenance/memory-governance-cron.ts +447 -0
  884. package/src/maintenance/memory-governance.ts +1039 -0
  885. package/src/maintenance/migrate-observations.ts +216 -0
  886. package/src/maintenance/observation-ledger-utils.ts +54 -0
  887. package/src/maintenance/pattern-reinforcement.test.ts +875 -0
  888. package/src/maintenance/pattern-reinforcement.ts +369 -0
  889. package/src/maintenance/purge.ts +334 -0
  890. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +78 -0
  891. package/src/maintenance/rebuild-memory-projection.ts +1234 -0
  892. package/src/maintenance/rebuild-observations.ts +178 -0
  893. package/src/maintenance/tier-stats.test.ts +378 -0
  894. package/src/maintenance/tier-stats.ts +222 -0
  895. package/src/mcp-memory-inspector-app.ts +421 -0
  896. package/src/memory-action-policy.ts +80 -0
  897. package/src/memory-cache.ts +208 -0
  898. package/src/memory-extension/claude-code-publisher.ts +51 -0
  899. package/src/memory-extension/codex-publisher.ts +149 -0
  900. package/src/memory-extension/hermes-publisher.ts +51 -0
  901. package/src/memory-extension/index.ts +100 -0
  902. package/src/memory-extension/shared-instructions.ts +133 -0
  903. package/src/memory-extension/types.ts +86 -0
  904. package/src/memory-extension-host/host-discovery.ts +276 -0
  905. package/src/memory-extension-host/index.ts +14 -0
  906. package/src/memory-extension-host/render-extensions-block.ts +73 -0
  907. package/src/memory-extension-host/types.ts +21 -0
  908. package/src/memory-lifecycle-ledger-utils.ts +116 -0
  909. package/src/memory-projection-format.ts +11 -0
  910. package/src/memory-projection-store.ts +951 -0
  911. package/src/memory-provenance.test.ts +196 -0
  912. package/src/memory-provenance.ts +484 -0
  913. package/src/memory-worth-bench.test.ts +71 -0
  914. package/src/memory-worth-bench.ts +265 -0
  915. package/src/memory-worth-filter.test.ts +209 -0
  916. package/src/memory-worth-filter.ts +204 -0
  917. package/src/memory-worth-frontmatter.test.ts +311 -0
  918. package/src/memory-worth-outcomes.test.ts +316 -0
  919. package/src/memory-worth-outcomes.ts +286 -0
  920. package/src/memory-worth.test.ts +317 -0
  921. package/src/memory-worth.ts +215 -0
  922. package/src/message-parts/index.ts +806 -0
  923. package/src/message-parts/message-parts.test.ts +421 -0
  924. package/src/migrate/from-engram.ts +789 -0
  925. package/src/model-registry.ts +313 -0
  926. package/src/models-json.ts +76 -0
  927. package/src/namespaces/migrate.ts +187 -0
  928. package/src/namespaces/path.ts +25 -0
  929. package/src/namespaces/principal.test.ts +195 -0
  930. package/src/namespaces/principal.ts +86 -0
  931. package/src/namespaces/search.test.ts +105 -0
  932. package/src/namespaces/search.ts +233 -0
  933. package/src/namespaces/storage.ts +74 -0
  934. package/src/native-knowledge.ts +1823 -0
  935. package/src/negative.ts +72 -0
  936. package/src/network/tailscale.ts +179 -0
  937. package/src/network/webdav.ts +385 -0
  938. package/src/objective-state-writers.ts +951 -0
  939. package/src/objective-state.ts +320 -0
  940. package/src/onboarding/index.ts +529 -0
  941. package/src/openai-chat-compat.ts +56 -0
  942. package/src/operator-toolkit.ts +2132 -0
  943. package/src/opik-exporter.test.ts +72 -0
  944. package/src/opik-exporter.ts +587 -0
  945. package/src/orchestrator-extraction-queue.test.ts +197 -0
  946. package/src/orchestrator-flush.test.ts +1171 -0
  947. package/src/orchestrator-pattern-reinforcement.test.ts +128 -0
  948. package/src/orchestrator-source-attribution.test.ts +701 -0
  949. package/src/orchestrator.ts +16368 -0
  950. package/src/page-versioning.ts +450 -0
  951. package/src/patterns-cli.ts +574 -0
  952. package/src/peers/index.ts +54 -0
  953. package/src/peers/migrate-from-identity-anchor.test.ts +291 -0
  954. package/src/peers/migrate-from-identity-anchor.ts +350 -0
  955. package/src/peers/peers.test.ts +419 -0
  956. package/src/peers/profile-reasoner.ts +694 -0
  957. package/src/peers/storage.ts +1350 -0
  958. package/src/peers/types.ts +138 -0
  959. package/src/plugin-id.ts +84 -0
  960. package/src/policy-runtime.ts +209 -0
  961. package/src/procedural/procedure-miner.ts +150 -0
  962. package/src/procedural/procedure-recall.ts +93 -0
  963. package/src/procedural/procedure-stats.ts +213 -0
  964. package/src/procedural/procedure-types.ts +132 -0
  965. package/src/procedural/reinforcement-core.test.ts +132 -0
  966. package/src/procedural/reinforcement-core.ts +73 -0
  967. package/src/profiling.test.ts +263 -0
  968. package/src/profiling.ts +435 -0
  969. package/src/projection/index.ts +398 -0
  970. package/src/qmd-recall-cache.test.ts +138 -0
  971. package/src/qmd-recall-cache.ts +111 -0
  972. package/src/qmd.test.ts +257 -0
  973. package/src/qmd.ts +2614 -0
  974. package/src/reasoning-trace-recall.ts +201 -0
  975. package/src/reasoning-trace-types.ts +235 -0
  976. package/src/recall-audit-anomaly.test.ts +246 -0
  977. package/src/recall-audit-anomaly.ts +297 -0
  978. package/src/recall-audit.test.ts +51 -0
  979. package/src/recall-audit.ts +72 -0
  980. package/src/recall-budget-config.test.ts +87 -0
  981. package/src/recall-disclosure-escalation.test.ts +196 -0
  982. package/src/recall-disclosure-escalation.ts +158 -0
  983. package/src/recall-disclosure-shaping.test.ts +146 -0
  984. package/src/recall-disclosure.test.ts +214 -0
  985. package/src/recall-explain-renderer.test.ts +140 -0
  986. package/src/recall-explain-renderer.ts +356 -0
  987. package/src/recall-mmr.test.ts +808 -0
  988. package/src/recall-mmr.ts +607 -0
  989. package/src/recall-qos.test.ts +85 -0
  990. package/src/recall-qos.ts +82 -0
  991. package/src/recall-query-policy.ts +221 -0
  992. package/src/recall-state.test.ts +233 -0
  993. package/src/recall-state.ts +456 -0
  994. package/src/recall-tag-filter.ts +143 -0
  995. package/src/recall-tokenization.ts +35 -0
  996. package/src/recall-xray-cli.test.ts +118 -0
  997. package/src/recall-xray-cli.ts +100 -0
  998. package/src/recall-xray-disclosure-telemetry.test.ts +183 -0
  999. package/src/recall-xray-renderer.test.ts +539 -0
  1000. package/src/recall-xray-renderer.ts +487 -0
  1001. package/src/recall-xray.test.ts +503 -0
  1002. package/src/recall-xray.ts +621 -0
  1003. package/src/reconstruct.ts +41 -0
  1004. package/src/release-changelog.ts +35 -0
  1005. package/src/relevance.ts +67 -0
  1006. package/src/replay/normalizers/chatgpt.ts +133 -0
  1007. package/src/replay/normalizers/claude.ts +102 -0
  1008. package/src/replay/normalizers/openclaw.ts +119 -0
  1009. package/src/replay/normalizers/shared.ts +69 -0
  1010. package/src/replay/runner.ts +197 -0
  1011. package/src/replay/types.ts +143 -0
  1012. package/src/rerank.test.ts +48 -0
  1013. package/src/rerank.ts +176 -0
  1014. package/src/resolve-auth-token.test.ts +226 -0
  1015. package/src/resolve-auth-token.ts +151 -0
  1016. package/src/resolve-provider-secret.test.ts +187 -0
  1017. package/src/resolve-provider-secret.ts +410 -0
  1018. package/src/response-guidance-recall.test.ts +3952 -0
  1019. package/src/response-guidance-recall.ts +4431 -0
  1020. package/src/resume-bundles.ts +415 -0
  1021. package/src/retrieval-agents.ts +623 -0
  1022. package/src/retrieval-tiers.ts +25 -0
  1023. package/src/retrieval.ts +104 -0
  1024. package/src/review/index.test.ts +201 -0
  1025. package/src/review/index.ts +536 -0
  1026. package/src/routing/engine.ts +162 -0
  1027. package/src/routing/store.ts +321 -0
  1028. package/src/runtime/better-sqlite.test.ts +32 -0
  1029. package/src/runtime/better-sqlite.ts +76 -0
  1030. package/src/runtime/child-process.ts +67 -0
  1031. package/src/runtime/env.ts +48 -0
  1032. package/src/sanitize.ts +58 -0
  1033. package/src/schemas.ts +449 -0
  1034. package/src/sdk-compat.ts +87 -0
  1035. package/src/search/document-scanner.ts +96 -0
  1036. package/src/search/embed-helper.ts +142 -0
  1037. package/src/search/factory.ts +189 -0
  1038. package/src/search/index.ts +10 -0
  1039. package/src/search/lancedb-backend.ts +342 -0
  1040. package/src/search/meilisearch-backend.ts +232 -0
  1041. package/src/search/noop-backend.ts +57 -0
  1042. package/src/search/orama-backend.ts +358 -0
  1043. package/src/search/port.ts +86 -0
  1044. package/src/search/remote-backend.ts +124 -0
  1045. package/src/secure-store/cipher.ts +271 -0
  1046. package/src/secure-store/cli-handlers.ts +355 -0
  1047. package/src/secure-store/cli-renderer.ts +131 -0
  1048. package/src/secure-store/header.ts +373 -0
  1049. package/src/secure-store/index.ts +137 -0
  1050. package/src/secure-store/kdf.ts +263 -0
  1051. package/src/secure-store/keyring.ts +106 -0
  1052. package/src/secure-store/metadata.ts +394 -0
  1053. package/src/secure-store/passphrase-reader.ts +252 -0
  1054. package/src/secure-store/secure-fs.ts +571 -0
  1055. package/src/secure-store/secure-store.test.ts +755 -0
  1056. package/src/semantic-chunking.ts +545 -0
  1057. package/src/semantic-consolidation.test.ts +182 -0
  1058. package/src/semantic-consolidation.ts +432 -0
  1059. package/src/semantic-rule-promotion.ts +183 -0
  1060. package/src/semantic-rule-verifier.ts +160 -0
  1061. package/src/session-integrity.ts +569 -0
  1062. package/src/session-observer-bands.ts +11 -0
  1063. package/src/session-observer-state.ts +346 -0
  1064. package/src/session-toggles.test.ts +96 -0
  1065. package/src/session-toggles.ts +159 -0
  1066. package/src/shared-context/manager.ts +810 -0
  1067. package/src/signal.ts +84 -0
  1068. package/src/skills-registry.test.ts +277 -0
  1069. package/src/skills-registry.ts +120 -0
  1070. package/src/source-attribution-roundtrip.test.ts +215 -0
  1071. package/src/source-attribution.test.ts +1425 -0
  1072. package/src/source-attribution.ts +639 -0
  1073. package/src/spaces/index.ts +627 -0
  1074. package/src/storage-paths.ts +117 -0
  1075. package/src/storage.ts +6657 -0
  1076. package/src/store-contract.ts +55 -0
  1077. package/src/summarizer.ts +844 -0
  1078. package/src/summary-snapshot.test.ts +681 -0
  1079. package/src/summary-snapshot.ts +238 -0
  1080. package/src/surfaces/dreams.test.ts +394 -0
  1081. package/src/surfaces/dreams.ts +346 -0
  1082. package/src/surfaces/heartbeat.test.ts +415 -0
  1083. package/src/surfaces/heartbeat.ts +325 -0
  1084. package/src/sync/index.ts +308 -0
  1085. package/src/targeted-fact-recall.test.ts +1694 -0
  1086. package/src/targeted-fact-recall.ts +2905 -0
  1087. package/src/taxonomy/default-taxonomy.ts +87 -0
  1088. package/src/taxonomy/index.ts +26 -0
  1089. package/src/taxonomy/resolver-doc-generator.ts +57 -0
  1090. package/src/taxonomy/resolver.ts +184 -0
  1091. package/src/taxonomy/taxonomy-loader.ts +186 -0
  1092. package/src/taxonomy/types.ts +48 -0
  1093. package/src/telemetry-transcript.ts +70 -0
  1094. package/src/temporal-index.ts +890 -0
  1095. package/src/temporal-supersession.test.ts +2703 -0
  1096. package/src/temporal-supersession.ts +493 -0
  1097. package/src/temporal-validity.test.ts +448 -0
  1098. package/src/temporal-validity.ts +123 -0
  1099. package/src/threading.ts +395 -0
  1100. package/src/tier-migration.ts +124 -0
  1101. package/src/tier-routing.ts +102 -0
  1102. package/src/tmt.ts +462 -0
  1103. package/src/tokens.test.ts +178 -0
  1104. package/src/tokens.ts +279 -0
  1105. package/src/topics.ts +147 -0
  1106. package/src/training-export/cli-date-validation.test.ts +258 -0
  1107. package/src/training-export/converter.test.ts +452 -0
  1108. package/src/training-export/converter.ts +319 -0
  1109. package/src/training-export/date-parse.ts +117 -0
  1110. package/src/training-export/index.ts +26 -0
  1111. package/src/training-export/registry.test.ts +85 -0
  1112. package/src/training-export/registry.ts +57 -0
  1113. package/src/training-export/types.ts +31 -0
  1114. package/src/transcript.ts +1179 -0
  1115. package/src/transfer/autodetect.ts +30 -0
  1116. package/src/transfer/backup.ts +138 -0
  1117. package/src/transfer/capsule-crypto.ts +485 -0
  1118. package/src/transfer/capsule-encrypt.test.ts +690 -0
  1119. package/src/transfer/capsule-export.ts +543 -0
  1120. package/src/transfer/capsule-fork.ts +375 -0
  1121. package/src/transfer/capsule-import.ts +564 -0
  1122. package/src/transfer/capsule-merge.ts +433 -0
  1123. package/src/transfer/conflict-policy.ts +16 -0
  1124. package/src/transfer/constants.ts +13 -0
  1125. package/src/transfer/exclusions.ts +37 -0
  1126. package/src/transfer/export-json.ts +65 -0
  1127. package/src/transfer/export-md.ts +59 -0
  1128. package/src/transfer/export-sqlite.ts +52 -0
  1129. package/src/transfer/fs-utils.ts +269 -0
  1130. package/src/transfer/import-json.ts +108 -0
  1131. package/src/transfer/import-md.ts +84 -0
  1132. package/src/transfer/import-sqlite.ts +100 -0
  1133. package/src/transfer/integrity.ts +71 -0
  1134. package/src/transfer/sqlite-schema.ts +16 -0
  1135. package/src/transfer/types.ts +297 -0
  1136. package/src/trust-zones.ts +1186 -0
  1137. package/src/types.ts +3074 -0
  1138. package/src/user-model.test.ts +124 -0
  1139. package/src/user-model.ts +162 -0
  1140. package/src/utility-learner.ts +353 -0
  1141. package/src/utility-runtime.ts +88 -0
  1142. package/src/utility-telemetry.ts +215 -0
  1143. package/src/utils/category-dir.ts +44 -0
  1144. package/src/utils/errno.ts +6 -0
  1145. package/src/utils/iso-timestamp.test.ts +37 -0
  1146. package/src/utils/iso-timestamp.ts +164 -0
  1147. package/src/utils/path.ts +26 -0
  1148. package/src/verified-recall.ts +138 -0
  1149. package/src/version-utils.test.ts +10 -0
  1150. package/src/version-utils.ts +9 -0
  1151. package/src/whitespace.ts +10 -0
  1152. package/src/work/board.ts +359 -0
  1153. package/src/work/boundary.ts +107 -0
  1154. package/src/work/storage.ts +436 -0
  1155. package/src/work/types.ts +82 -0
  1156. package/src/work-product-ledger.ts +265 -0
  1157. package/dist/access-service-DDjzFALq.d.ts +0 -2088
  1158. package/dist/capsule-crypto-SJS5VVAP.js +0 -18
  1159. package/dist/capsule-export-7QNCBZOQ.js +0 -17
  1160. package/dist/capsule-import-EPBHD2EN.js +0 -16
  1161. package/dist/capsule-merge-DI7PNQ2H.js +0 -189
  1162. package/dist/chunk-23ZZK64Y.js +0 -26
  1163. package/dist/chunk-23ZZK64Y.js.map +0 -1
  1164. package/dist/chunk-242S3I2A.js +0 -647
  1165. package/dist/chunk-2LGMW3DJ.js +0 -111
  1166. package/dist/chunk-3B6KIRBH.js +0 -5213
  1167. package/dist/chunk-3B6KIRBH.js.map +0 -1
  1168. package/dist/chunk-457A4P3L.js +0 -119
  1169. package/dist/chunk-457A4P3L.js.map +0 -1
  1170. package/dist/chunk-4IS4SXIQ.js +0 -2040
  1171. package/dist/chunk-4YM32CRU.js +0 -721
  1172. package/dist/chunk-6TBWYBJ3.js +0 -236
  1173. package/dist/chunk-74EMIVE4.js +0 -329
  1174. package/dist/chunk-74EMIVE4.js.map +0 -1
  1175. package/dist/chunk-767ODGE6.js +0 -183
  1176. package/dist/chunk-7V22HTMD.js +0 -623
  1177. package/dist/chunk-7V22HTMD.js.map +0 -1
  1178. package/dist/chunk-7ZM3BFKK.js +0 -9705
  1179. package/dist/chunk-7ZM3BFKK.js.map +0 -1
  1180. package/dist/chunk-AQJNPMOA.js +0 -643
  1181. package/dist/chunk-AQJNPMOA.js.map +0 -1
  1182. package/dist/chunk-ASAITVLA.js +0 -64
  1183. package/dist/chunk-ASAITVLA.js.map +0 -1
  1184. package/dist/chunk-BBE34QBJ.js +0 -275
  1185. package/dist/chunk-BBE34QBJ.js.map +0 -1
  1186. package/dist/chunk-BZSQEPRW.js +0 -14710
  1187. package/dist/chunk-BZSQEPRW.js.map +0 -1
  1188. package/dist/chunk-CPKTBRS2.js +0 -891
  1189. package/dist/chunk-CPKTBRS2.js.map +0 -1
  1190. package/dist/chunk-D4GAOFF6.js +0 -562
  1191. package/dist/chunk-D4GAOFF6.js.map +0 -1
  1192. package/dist/chunk-D54LZC5L.js +0 -147
  1193. package/dist/chunk-DF3RVK3X.js +0 -119
  1194. package/dist/chunk-DF3RVK3X.js.map +0 -1
  1195. package/dist/chunk-DZZPC36E.js +0 -1451
  1196. package/dist/chunk-DZZPC36E.js.map +0 -1
  1197. package/dist/chunk-E2UCDP5S.js +0 -570
  1198. package/dist/chunk-E6K4NIEU.js +0 -747
  1199. package/dist/chunk-E6K4NIEU.js.map +0 -1
  1200. package/dist/chunk-EEQLFRUM.js +0 -89
  1201. package/dist/chunk-ETOW6ACV.js +0 -158
  1202. package/dist/chunk-ETOW6ACV.js.map +0 -1
  1203. package/dist/chunk-FMEBPEAO.js +0 -347
  1204. package/dist/chunk-FMEBPEAO.js.map +0 -1
  1205. package/dist/chunk-FQDPCE3I.js +0 -1837
  1206. package/dist/chunk-FQDPCE3I.js.map +0 -1
  1207. package/dist/chunk-FYIYMQ5N.js +0 -221
  1208. package/dist/chunk-FYIYMQ5N.js.map +0 -1
  1209. package/dist/chunk-G2WADRQ3.js +0 -219
  1210. package/dist/chunk-G4SK7DSQ.js +0 -121
  1211. package/dist/chunk-GVPWB7EY.js +0 -390
  1212. package/dist/chunk-GVPWB7EY.js.map +0 -1
  1213. package/dist/chunk-HELQZFZO.js +0 -1075
  1214. package/dist/chunk-HL5LRPNA.js +0 -1914
  1215. package/dist/chunk-HL5LRPNA.js.map +0 -1
  1216. package/dist/chunk-HQZVVSVB.js +0 -147
  1217. package/dist/chunk-HQZVVSVB.js.map +0 -1
  1218. package/dist/chunk-HY3L4WKC.js +0 -2195
  1219. package/dist/chunk-HY3L4WKC.js.map +0 -1
  1220. package/dist/chunk-IB3BFHGN.js +0 -228
  1221. package/dist/chunk-IXEJRKCZ.js +0 -18
  1222. package/dist/chunk-JBMSGZEQ.js +0 -441
  1223. package/dist/chunk-JBMSGZEQ.js.map +0 -1
  1224. package/dist/chunk-JESOB2HO.js +0 -108
  1225. package/dist/chunk-JKDVIE52.js +0 -272
  1226. package/dist/chunk-JRNQ3RNA.js +0 -284
  1227. package/dist/chunk-JRNQ3RNA.js.map +0 -1
  1228. package/dist/chunk-K6WK37A6.js +0 -865
  1229. package/dist/chunk-K6WK37A6.js.map +0 -1
  1230. package/dist/chunk-MARWOCVP.js +0 -48
  1231. package/dist/chunk-MNU6ZBWT.js +0 -4454
  1232. package/dist/chunk-MNU6ZBWT.js.map +0 -1
  1233. package/dist/chunk-N5AKDXAI.js +0 -74
  1234. package/dist/chunk-OA3L7BFR.js +0 -183
  1235. package/dist/chunk-OA3L7BFR.js.map +0 -1
  1236. package/dist/chunk-OR64ZGRZ.js +0 -23
  1237. package/dist/chunk-P77UEOU2.js +0 -1521
  1238. package/dist/chunk-P77UEOU2.js.map +0 -1
  1239. package/dist/chunk-PH4C2U43.js +0 -239
  1240. package/dist/chunk-PH4C2U43.js.map +0 -1
  1241. package/dist/chunk-RVPLBATS.js +0 -1586
  1242. package/dist/chunk-RVPLBATS.js.map +0 -1
  1243. package/dist/chunk-U5JMRGKX.js +0 -340
  1244. package/dist/chunk-U5JMRGKX.js.map +0 -1
  1245. package/dist/chunk-URB2WSKZ.js +0 -350
  1246. package/dist/chunk-URB2WSKZ.js.map +0 -1
  1247. package/dist/chunk-UVMUAWVT.js +0 -596
  1248. package/dist/chunk-WEJG4TB5.js +0 -118
  1249. package/dist/chunk-X7HPGUVG.js +0 -271
  1250. package/dist/chunk-XAMBKFQS.js +0 -2777
  1251. package/dist/chunk-XAMBKFQS.js.map +0 -1
  1252. package/dist/chunk-XJKFSSDW.js +0 -726
  1253. package/dist/chunk-XJKFSSDW.js.map +0 -1
  1254. package/dist/chunk-XMHBH5H6.js +0 -283
  1255. package/dist/chunk-XMHBH5H6.js.map +0 -1
  1256. package/dist/chunk-XMVFHBHT.js +0 -277
  1257. package/dist/chunk-Y3VMVTYX.js +0 -53
  1258. package/dist/chunk-YNB73F22.js +0 -137
  1259. package/dist/chunk-YNB73F22.js.map +0 -1
  1260. package/dist/chunk-Z2E7VW55.js +0 -335
  1261. package/dist/chunk-Z2E7VW55.js.map +0 -1
  1262. package/dist/chunk-ZG7PTKBK.js +0 -2296
  1263. package/dist/chunk-ZNQN6ZTA.js +0 -135
  1264. package/dist/chunk-ZVTKDVVM.js +0 -827
  1265. package/dist/chunk-ZVTKDVVM.js.map +0 -1
  1266. package/dist/cli-BR8KpIU0.d.ts +0 -1259
  1267. package/dist/codex-materialize-CQlLTzke.d.ts +0 -139
  1268. package/dist/connectors-cli-DFGtY2DB.d.ts +0 -257
  1269. package/dist/contradiction-review-5LTTVDQV.js +0 -22
  1270. package/dist/contradiction-scan-QTXAMBUA.js +0 -414
  1271. package/dist/contradiction-scan-QTXAMBUA.js.map +0 -1
  1272. package/dist/engine-35M5BKQ7.js +0 -28
  1273. package/dist/fs-utils-IRVUFB6G.js +0 -30
  1274. package/dist/graph-edge-decay-PWB63GRE.js +0 -207
  1275. package/dist/memory-governance-IMPQZXFC.js +0 -37
  1276. package/dist/memory-projection-store-CY8TU40w.d.ts +0 -222
  1277. package/dist/orchestrator-DDMPqU6R.d.ts +0 -1792
  1278. package/dist/path-RMTY5Y5A.js +0 -9
  1279. package/dist/port-B6VEDIkC.d.ts +0 -53
  1280. package/dist/resolution-YGIBORXI.js +0 -101
  1281. package/dist/resolution-YGIBORXI.js.map +0 -1
  1282. package/dist/secure-store-4R2GSO7S.js +0 -156
  1283. package/dist/semantic-consolidation-ByBXb-sf.d.ts +0 -180
  1284. package/dist/state-store-3EH7HYIN.js +0 -16
  1285. package/dist/types-V3FJ26TF.js +0 -30
  1286. /package/dist/{capsule-crypto-SJS5VVAP.js.map → adapters/claude-code.js.map} +0 -0
  1287. /package/dist/{capsule-export-7QNCBZOQ.js.map → adapters/codex.js.map} +0 -0
  1288. /package/dist/{capsule-import-EPBHD2EN.js.map → adapters/hermes.js.map} +0 -0
  1289. /package/dist/{contradiction-review-5LTTVDQV.js.map → adapters/index.js.map} +0 -0
  1290. /package/dist/{engine-35M5BKQ7.js.map → adapters/registry.js.map} +0 -0
  1291. /package/dist/{fs-utils-IRVUFB6G.js.map → adapters/replit.js.map} +0 -0
  1292. /package/dist/{memory-governance-IMPQZXFC.js.map → adapters/types.js.map} +0 -0
  1293. /package/dist/{path-RMTY5Y5A.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
  1294. /package/dist/{capsule-merge-DI7PNQ2H.js.map → capsule-merge-4MGKE7C5.js.map} +0 -0
  1295. /package/dist/{chunk-G4SK7DSQ.js.map → chunk-2WWLHTZY.js.map} +0 -0
  1296. /package/dist/{chunk-X7HPGUVG.js.map → chunk-4CRG46BG.js.map} +0 -0
  1297. /package/dist/{chunk-UVMUAWVT.js.map → chunk-7IASACLB.js.map} +0 -0
  1298. /package/dist/{chunk-HELQZFZO.js.map → chunk-EDTHC6UD.js.map} +0 -0
  1299. /package/dist/{chunk-4YM32CRU.js.map → chunk-EFJ3MQ4V.js.map} +0 -0
  1300. /package/dist/{chunk-E2UCDP5S.js.map → chunk-FBYESMQ2.js.map} +0 -0
  1301. /package/dist/{chunk-D54LZC5L.js.map → chunk-FDU6HUUL.js.map} +0 -0
  1302. /package/dist/{chunk-IB3BFHGN.js.map → chunk-GGKRUQOO.js.map} +0 -0
  1303. /package/dist/{chunk-242S3I2A.js.map → chunk-GL6I6MEQ.js.map} +0 -0
  1304. /package/dist/{secure-store-4R2GSO7S.js.map → chunk-HHLLAQGZ.js.map} +0 -0
  1305. /package/dist/{chunk-4IS4SXIQ.js.map → chunk-HXXBL2KD.js.map} +0 -0
  1306. /package/dist/{chunk-767ODGE6.js.map → chunk-KNKUID7G.js.map} +0 -0
  1307. /package/dist/{chunk-6TBWYBJ3.js.map → chunk-LPMVBPA3.js.map} +0 -0
  1308. /package/dist/{chunk-WEJG4TB5.js.map → chunk-MC26UJIM.js.map} +0 -0
  1309. /package/dist/{chunk-JKDVIE52.js.map → chunk-MGKYQQYF.js.map} +0 -0
  1310. /package/dist/{chunk-Y3VMVTYX.js.map → chunk-MT4HVDUZ.js.map} +0 -0
  1311. /package/dist/{chunk-G2WADRQ3.js.map → chunk-MY6TPVXW.js.map} +0 -0
  1312. /package/dist/{chunk-OR64ZGRZ.js.map → chunk-NNVTUXEB.js.map} +0 -0
  1313. /package/dist/{chunk-JESOB2HO.js.map → chunk-P4NEIHUT.js.map} +0 -0
  1314. /package/dist/{chunk-IXEJRKCZ.js.map → chunk-QRNI5JBH.js.map} +0 -0
  1315. /package/dist/{chunk-EEQLFRUM.js.map → chunk-RRF5UOBJ.js.map} +0 -0
  1316. /package/dist/{state-store-3EH7HYIN.js.map → chunk-SEDEKFYQ.js.map} +0 -0
  1317. /package/dist/{chunk-2LGMW3DJ.js.map → chunk-U3PN77QT.js.map} +0 -0
  1318. /package/dist/{chunk-XMVFHBHT.js.map → chunk-U3WSW6PZ.js.map} +0 -0
  1319. /package/dist/{chunk-N5AKDXAI.js.map → chunk-UWVJF25J.js.map} +0 -0
  1320. /package/dist/{types-V3FJ26TF.js.map → chunk-V5OCT34X.js.map} +0 -0
  1321. /package/dist/{chunk-ZG7PTKBK.js.map → chunk-W3LR522O.js.map} +0 -0
  1322. /package/dist/{chunk-MARWOCVP.js.map → chunk-XIG5PDM7.js.map} +0 -0
  1323. /package/dist/{chunk-ZNQN6ZTA.js.map → chunk-XVZ7B3HG.js.map} +0 -0
  1324. /package/dist/{graph-edge-decay-PWB63GRE.js.map → graph-edge-decay-5DI5GUNL.js.map} +0 -0
@@ -0,0 +1,2272 @@
1
+ import {
2
+ coerceBool,
3
+ coerceInstallExtension,
4
+ coerceNumber
5
+ } from "./chunk-PHK3HARR.js";
6
+ import {
7
+ cloneDefaultSessionObserverBands
8
+ } from "./chunk-Z5LAYHGJ.js";
9
+ import {
10
+ normalizeEntitySchemas
11
+ } from "./chunk-4DJQYKMN.js";
12
+ import {
13
+ readEnvVar,
14
+ resolveHomeDir
15
+ } from "./chunk-XIG5PDM7.js";
16
+ import {
17
+ log
18
+ } from "./chunk-2ODBA7MQ.js";
19
+
20
+ // src/config.ts
21
+ import path from "path";
22
+ var DEFAULT_MEMORY_DIR = path.join(
23
+ resolveHomeDir(),
24
+ ".openclaw",
25
+ "workspace",
26
+ "memory",
27
+ "local"
28
+ );
29
+ var DEFAULT_WORKSPACE_DIR = path.join(
30
+ resolveHomeDir(),
31
+ ".openclaw",
32
+ "workspace"
33
+ );
34
+ var DEFAULT_INIT_GATE_TIMEOUT_MS = 3e4;
35
+ var CLIENT_SECRET_FIELD = ["client", "Secret"].join("");
36
+ var REFRESH_TOKEN_FIELD = ["refresh", "Token"].join("");
37
+ var LEGACY_ACTIVE_RECALL_CUSTOM_FIELD = [
38
+ "activeRecall",
39
+ "Prompt",
40
+ "Override"
41
+ ].join("");
42
+ function parseBoundedIntegerMs(value, fallback, min, max) {
43
+ const coerced = coerceNumber(value);
44
+ if (coerced === void 0) return fallback;
45
+ return Math.min(max, Math.max(min, Math.floor(coerced)));
46
+ }
47
+ function parsePositiveInteger(value, keyName) {
48
+ if (value === void 0 || value === null) return void 0;
49
+ const coerced = coerceNumber(value);
50
+ if (coerced === void 0 || !Number.isFinite(coerced) || !Number.isInteger(coerced) || coerced <= 0) {
51
+ throw new Error(
52
+ `${keyName} must be a positive integer; got ${JSON.stringify(value)}`
53
+ );
54
+ }
55
+ return coerced;
56
+ }
57
+ function parseBoundedPositiveInteger(value, min, max, keyName) {
58
+ const parsed = parsePositiveInteger(value, keyName);
59
+ if (parsed === void 0) return void 0;
60
+ return Math.max(min, Math.min(max, parsed));
61
+ }
62
+ function parseQmdSupportedVersion(value) {
63
+ if (value === void 0 || value === null) return "2.5.1";
64
+ if (typeof value !== "string") {
65
+ throw new Error(`qmdSupportedVersion must be a semantic version string; got ${JSON.stringify(value)}`);
66
+ }
67
+ const normalized = value.trim();
68
+ if (!/^\d+\.\d+\.\d+$/.test(normalized)) {
69
+ throw new Error(
70
+ `qmdSupportedVersion must be a semantic version string like "2.5.1"; got ${JSON.stringify(value)}`
71
+ );
72
+ }
73
+ return normalized;
74
+ }
75
+ function parseQmdGpuBackend(value) {
76
+ if (value === void 0 || value === null) return void 0;
77
+ if (value === false) return "false";
78
+ if (typeof value !== "string") {
79
+ throw new Error(`qmdGpuBackend must be one of "auto", "metal", "cuda", "vulkan", or false; got ${JSON.stringify(value)}`);
80
+ }
81
+ const normalized = value.trim().toLowerCase();
82
+ if (normalized === "auto" || normalized === "metal" || normalized === "cuda" || normalized === "vulkan" || normalized === "false") {
83
+ return normalized;
84
+ }
85
+ throw new Error(`qmdGpuBackend must be one of "auto", "metal", "cuda", "vulkan", or false; got ${JSON.stringify(value)}`);
86
+ }
87
+ function parseQmdChunkStrategy(value) {
88
+ if (value === void 0 || value === null) return "auto";
89
+ if (typeof value !== "string") {
90
+ throw new Error(`qmdChunkStrategy must be "auto" or "regex"; got ${JSON.stringify(value)}`);
91
+ }
92
+ const normalized = value.trim().toLowerCase();
93
+ if (normalized === "auto" || normalized === "regex") return normalized;
94
+ throw new Error(`qmdChunkStrategy must be "auto" or "regex"; got ${JSON.stringify(value)}`);
95
+ }
96
+ function parseOptionalNonEmptyString(value) {
97
+ if (typeof value !== "string") return void 0;
98
+ const normalized = value.trim();
99
+ return normalized.length > 0 ? normalized : void 0;
100
+ }
101
+ function parseIntegerAtLeast(value, fallback, min, keyName) {
102
+ if (value === void 0 || value === null) return fallback;
103
+ const coerced = coerceNumber(value);
104
+ if (coerced === void 0 || !Number.isFinite(coerced) || !Number.isInteger(coerced) || coerced < min) {
105
+ throw new Error(
106
+ `${keyName} must be an integer greater than or equal to ${min}; got ${JSON.stringify(value)}`
107
+ );
108
+ }
109
+ return coerced;
110
+ }
111
+ function coerceBooleanLike(value) {
112
+ if (typeof value === "boolean") return value;
113
+ if (typeof value === "number") {
114
+ if (value === 1) return true;
115
+ if (value === 0) return false;
116
+ return void 0;
117
+ }
118
+ if (typeof value === "string") {
119
+ const normalized = value.trim().toLowerCase();
120
+ if (normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on") {
121
+ return true;
122
+ }
123
+ if (normalized === "false" || normalized === "0" || normalized === "no" || normalized === "off") {
124
+ return false;
125
+ }
126
+ }
127
+ return void 0;
128
+ }
129
+ function isOpenaiApiKeyDisabled(value) {
130
+ return value === false || typeof value === "string" && value.trim().toLowerCase() === "false";
131
+ }
132
+ function isSecretRefShape(value) {
133
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
134
+ const obj = value;
135
+ return typeof obj.source === "string" && obj.source.trim().length > 0;
136
+ }
137
+ function parseAgentAccessAuthToken(raw) {
138
+ if (raw === void 0 || raw === null) {
139
+ return readEnvVar("OPENCLAW_REMNIC_ACCESS_TOKEN") ?? readEnvVar("OPENCLAW_ENGRAM_ACCESS_TOKEN");
140
+ }
141
+ if (typeof raw === "string") {
142
+ if (raw.trim().length === 0) {
143
+ return readEnvVar("OPENCLAW_REMNIC_ACCESS_TOKEN") ?? readEnvVar("OPENCLAW_ENGRAM_ACCESS_TOKEN");
144
+ }
145
+ return resolveEnvVars(raw);
146
+ }
147
+ if (isSecretRefShape(raw)) {
148
+ return raw;
149
+ }
150
+ throw new Error(
151
+ "unsupported SecretRef shape for agentAccessHttp.authToken \u2014 expected a string or an object with a non-empty `source` field (see https://github.com/joshuaswarren/remnic/issues/757)"
152
+ );
153
+ }
154
+ function resolveEnvVars(value) {
155
+ const resolved = value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_, envVar) => {
156
+ const envValue = readEnvVar(envVar);
157
+ if (!envValue) {
158
+ throw new Error(`Environment variable ${envVar} is not set`);
159
+ }
160
+ return envValue;
161
+ });
162
+ const remaining = resolved.match(/\$\{[^}]*\}/);
163
+ if (remaining) {
164
+ throw new Error(`Malformed environment variable placeholder: ${remaining[0]}`);
165
+ }
166
+ return resolved;
167
+ }
168
+ function normalizeOpenaiBaseUrl(value, source) {
169
+ if (!value) return void 0;
170
+ const trimmed = value.trim();
171
+ if (trimmed.length === 0) return void 0;
172
+ let parsed;
173
+ try {
174
+ parsed = new URL(trimmed);
175
+ } catch {
176
+ log.warn(`ignoring invalid openaiBaseUrl from ${source}: not a valid URL`);
177
+ return void 0;
178
+ }
179
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
180
+ log.warn(
181
+ `ignoring openaiBaseUrl from ${source}: unsupported URL scheme (${parsed.protocol.replace(":", "")})`
182
+ );
183
+ return void 0;
184
+ }
185
+ if (parsed.protocol === "http:") {
186
+ log.warn(`openaiBaseUrl from ${source} is using insecure http; prefer https`);
187
+ }
188
+ let url = parsed.toString();
189
+ while (url.endsWith("/")) url = url.slice(0, -1);
190
+ return url;
191
+ }
192
+ function normalizeMemoryRelativeDir(raw, fallback) {
193
+ if (typeof raw !== "string") return fallback;
194
+ const trimmed = raw.trim();
195
+ if (trimmed.length === 0) return fallback;
196
+ const normalized = trimmed.replace(/\\/g, "/").split("/").filter((segment) => segment.length > 0 && segment !== "." && segment !== "..").join("/");
197
+ return normalized.length > 0 ? normalized : fallback;
198
+ }
199
+ function parseContradictionScanConfig(raw) {
200
+ if (!raw || typeof raw !== "object") {
201
+ return {
202
+ enabled: false,
203
+ similarityFloor: 0.82,
204
+ topicOverlapFloor: 0.4,
205
+ maxPairsPerRun: 500,
206
+ cooldownDays: 14,
207
+ autoMergeDuplicates: false
208
+ };
209
+ }
210
+ const src = raw;
211
+ const simFloor = coerceNumber(src.similarityFloor) ?? 0.82;
212
+ const topicFloor = coerceNumber(src.topicOverlapFloor) ?? 0.4;
213
+ const maxPairs = coerceNumber(src.maxPairsPerRun) ?? 500;
214
+ const cooldown = coerceNumber(src.cooldownDays) ?? 14;
215
+ return {
216
+ enabled: coerceBool(src.enabled) === true,
217
+ similarityFloor: Math.min(1, Math.max(0, simFloor)),
218
+ topicOverlapFloor: Math.min(1, Math.max(0, topicFloor)),
219
+ maxPairsPerRun: Math.max(1, maxPairs),
220
+ cooldownDays: Math.max(0, cooldown),
221
+ autoMergeDuplicates: coerceBool(src.autoMergeDuplicates) === true
222
+ };
223
+ }
224
+ function parseSemanticChunkingConfig(raw) {
225
+ if (!raw || typeof raw !== "object") return {};
226
+ const src = raw;
227
+ const out = {};
228
+ if (typeof src.targetTokens === "number") out.targetTokens = src.targetTokens;
229
+ if (typeof src.minTokens === "number") out.minTokens = src.minTokens;
230
+ if (typeof src.maxTokens === "number") out.maxTokens = src.maxTokens;
231
+ if (typeof src.smoothingWindowSize === "number") out.smoothingWindowSize = src.smoothingWindowSize;
232
+ if (typeof src.boundaryThresholdStdDevs === "number") out.boundaryThresholdStdDevs = src.boundaryThresholdStdDevs;
233
+ if (typeof src.embeddingBatchSize === "number") out.embeddingBatchSize = src.embeddingBatchSize;
234
+ if (typeof src.fallbackToRecursive === "boolean") out.fallbackToRecursive = src.fallbackToRecursive;
235
+ return out;
236
+ }
237
+ var DEFAULT_REASONING_MODEL = "gpt-5.5";
238
+ var VALID_EFFORTS = ["none", "low", "medium", "high"];
239
+ var VALID_TRIGGERS = ["smart", "every_n", "time_based"];
240
+ var VALID_IDENTITY_INJECTION_MODES = ["recovery_only", "minimal", "full"];
241
+ var VALID_MEMORY_OS_PRESETS = [
242
+ "conservative",
243
+ "balanced",
244
+ "research-max",
245
+ "local-llm-heavy"
246
+ ];
247
+ var VALID_SLOT_MISMATCH_MODES = ["error", "warn", "silent"];
248
+ var VALID_CODEX_COMPACTION_FLUSH_MODES = ["signal", "heuristic", "auto"];
249
+ var VALID_MEMORY_CATEGORIES = /* @__PURE__ */ new Set([
250
+ "fact",
251
+ "preference",
252
+ "correction",
253
+ "entity",
254
+ "decision",
255
+ "relationship",
256
+ "principle",
257
+ "commitment",
258
+ "moment",
259
+ "skill",
260
+ "rule",
261
+ "procedure",
262
+ "reasoning_trace"
263
+ ]);
264
+ var DEFAULT_BEHAVIOR_LOOP_PROTECTED_PARAMS = [
265
+ "maxMemoryTokens",
266
+ "qmdMaxResults",
267
+ "qmdColdMaxResults",
268
+ "recallPlannerMaxQmdResultsMinimal",
269
+ "verbatimArtifactsMaxRecall"
270
+ ];
271
+ var MEMORY_OS_PRESET_ALIASES = {
272
+ research: "research-max"
273
+ };
274
+ var MEMORY_OS_PRESETS = {
275
+ conservative: {
276
+ maxMemoryTokens: 1500,
277
+ recallPlannerMaxQmdResultsMinimal: 2,
278
+ recallPlannerMaxQmdResultsFull: 5,
279
+ queryAwareIndexingEnabled: false,
280
+ verbatimArtifactsEnabled: false,
281
+ verbatimArtifactsMaxRecall: 2,
282
+ rerankEnabled: false,
283
+ localLlmEnabled: false,
284
+ localLlmFastEnabled: false,
285
+ multiGraphMemoryEnabled: false,
286
+ graphRecallEnabled: false,
287
+ graphAssistInFullModeEnabled: false,
288
+ proactiveExtractionEnabled: false,
289
+ contextCompressionActionsEnabled: false,
290
+ compressionGuidelineLearningEnabled: false,
291
+ compressionGuidelineSemanticRefinementEnabled: false,
292
+ maxProactiveQuestionsPerExtraction: 0,
293
+ maxCompressionTokensPerHour: 0,
294
+ behaviorLoopAutoTuneEnabled: false,
295
+ // Issue #567 PR 4/5 flipped `procedural.enabled` default to `true`.
296
+ // The conservative preset intentionally keeps the feature OFF to
297
+ // match its restrictive intent (no proactive extraction, no
298
+ // compression guideline learning, etc.). Users who want procedural
299
+ // memory on a conservative preset must set `procedural.enabled: true`
300
+ // explicitly.
301
+ procedural: { enabled: false }
302
+ },
303
+ balanced: {
304
+ maxMemoryTokens: 2e3,
305
+ recallPlannerMaxQmdResultsMinimal: 4,
306
+ recallPlannerMaxQmdResultsFull: 8,
307
+ queryAwareIndexingEnabled: true,
308
+ verbatimArtifactsEnabled: true,
309
+ verbatimArtifactsMaxRecall: 4,
310
+ rerankEnabled: true,
311
+ rerankProvider: "local",
312
+ localLlmEnabled: false,
313
+ localLlmFastEnabled: false,
314
+ multiGraphMemoryEnabled: false,
315
+ graphRecallEnabled: false,
316
+ graphAssistInFullModeEnabled: false,
317
+ proactiveExtractionEnabled: false,
318
+ contextCompressionActionsEnabled: false,
319
+ compressionGuidelineLearningEnabled: false,
320
+ compressionGuidelineSemanticRefinementEnabled: false,
321
+ maxProactiveQuestionsPerExtraction: 2,
322
+ maxCompressionTokensPerHour: 1500,
323
+ behaviorLoopAutoTuneEnabled: false
324
+ },
325
+ "research-max": {
326
+ maxMemoryTokens: 3200,
327
+ recallPlannerMaxQmdResultsMinimal: 6,
328
+ recallPlannerMaxQmdResultsFull: 12,
329
+ queryAwareIndexingEnabled: true,
330
+ verbatimArtifactsEnabled: true,
331
+ verbatimArtifactsMaxRecall: 6,
332
+ rerankEnabled: true,
333
+ rerankProvider: "local",
334
+ localLlmEnabled: false,
335
+ localLlmFastEnabled: false,
336
+ multiGraphMemoryEnabled: true,
337
+ graphRecallEnabled: true,
338
+ graphAssistInFullModeEnabled: true,
339
+ proactiveExtractionEnabled: true,
340
+ contextCompressionActionsEnabled: true,
341
+ compressionGuidelineLearningEnabled: true,
342
+ compressionGuidelineSemanticRefinementEnabled: true,
343
+ explicitCueRecallEnabled: true,
344
+ explicitCueRecallMaxChars: 3200,
345
+ lcmEnabled: true,
346
+ maxProactiveQuestionsPerExtraction: 4,
347
+ maxCompressionTokensPerHour: 3e3,
348
+ behaviorLoopAutoTuneEnabled: true
349
+ },
350
+ "local-llm-heavy": {
351
+ maxMemoryTokens: 2400,
352
+ recallPlannerMaxQmdResultsMinimal: 4,
353
+ recallPlannerMaxQmdResultsFull: 8,
354
+ queryAwareIndexingEnabled: true,
355
+ verbatimArtifactsEnabled: true,
356
+ verbatimArtifactsMaxRecall: 4,
357
+ rerankEnabled: true,
358
+ rerankProvider: "local",
359
+ localLlmEnabled: true,
360
+ localLlmFastEnabled: true,
361
+ embeddingFallbackProvider: "local",
362
+ localLlmFallback: true,
363
+ multiGraphMemoryEnabled: false,
364
+ graphRecallEnabled: false,
365
+ graphAssistInFullModeEnabled: false,
366
+ proactiveExtractionEnabled: true,
367
+ contextCompressionActionsEnabled: true,
368
+ compressionGuidelineLearningEnabled: true,
369
+ compressionGuidelineSemanticRefinementEnabled: false,
370
+ maxProactiveQuestionsPerExtraction: 2,
371
+ maxCompressionTokensPerHour: 1500,
372
+ behaviorLoopAutoTuneEnabled: false
373
+ }
374
+ };
375
+ function resolveMemoryOsPreset(value) {
376
+ if (typeof value !== "string") return void 0;
377
+ const normalized = value.trim();
378
+ if (VALID_MEMORY_OS_PRESETS.includes(normalized)) {
379
+ return normalized;
380
+ }
381
+ return MEMORY_OS_PRESET_ALIASES[normalized];
382
+ }
383
+ function parseConfig(raw) {
384
+ const baseCfg = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
385
+ const memoryOsPreset = resolveMemoryOsPreset(baseCfg.memoryOsPreset);
386
+ let cfg;
387
+ if (memoryOsPreset) {
388
+ const preset = MEMORY_OS_PRESETS[memoryOsPreset];
389
+ const presetProcedural = preset.procedural && typeof preset.procedural === "object" && !Array.isArray(preset.procedural) ? preset.procedural : void 0;
390
+ const baseProcedural = baseCfg.procedural && typeof baseCfg.procedural === "object" && !Array.isArray(baseCfg.procedural) ? baseCfg.procedural : void 0;
391
+ const mergedProcedural = presetProcedural && baseProcedural ? { ...presetProcedural, ...baseProcedural } : baseProcedural ?? presetProcedural;
392
+ cfg = {
393
+ ...preset,
394
+ ...baseCfg,
395
+ memoryOsPreset
396
+ };
397
+ if (mergedProcedural !== void 0) {
398
+ cfg.procedural = mergedProcedural;
399
+ }
400
+ } else {
401
+ cfg = baseCfg;
402
+ }
403
+ const modelSource = cfg.modelSource === "gateway" ? "gateway" : "plugin";
404
+ const openaiApiKeyDisabled = isOpenaiApiKeyDisabled(cfg.openaiApiKey);
405
+ let apiKey;
406
+ if (openaiApiKeyDisabled) {
407
+ apiKey = void 0;
408
+ } else if (typeof cfg.openaiApiKey === "string" && cfg.openaiApiKey.length > 0) {
409
+ apiKey = resolveEnvVars(cfg.openaiApiKey);
410
+ } else if (modelSource === "gateway") {
411
+ apiKey = void 0;
412
+ } else {
413
+ apiKey = readEnvVar("OPENAI_API_KEY");
414
+ }
415
+ const model = typeof cfg.model === "string" && cfg.model.length > 0 ? cfg.model : DEFAULT_REASONING_MODEL;
416
+ const captureMode = cfg.captureMode === "explicit" || cfg.captureMode === "hybrid" ? cfg.captureMode : "implicit";
417
+ const rawEffort = cfg.reasoningEffort;
418
+ const reasoningEffort = rawEffort && VALID_EFFORTS.includes(rawEffort) ? rawEffort : "low";
419
+ const rawTrigger = cfg.triggerMode;
420
+ const triggerMode = rawTrigger && VALID_TRIGGERS.includes(rawTrigger) ? rawTrigger : "smart";
421
+ const rawSlotBehavior = cfg.slotBehavior && typeof cfg.slotBehavior === "object" && !Array.isArray(cfg.slotBehavior) ? cfg.slotBehavior : {};
422
+ const slotBehavior = {
423
+ requireExclusiveMemorySlot: rawSlotBehavior.requireExclusiveMemorySlot !== false,
424
+ onSlotMismatch: typeof rawSlotBehavior.onSlotMismatch === "string" && VALID_SLOT_MISMATCH_MODES.includes(
425
+ rawSlotBehavior.onSlotMismatch
426
+ ) ? rawSlotBehavior.onSlotMismatch : "error"
427
+ };
428
+ const rawDreaming = cfg.dreaming && typeof cfg.dreaming === "object" && !Array.isArray(cfg.dreaming) ? cfg.dreaming : {};
429
+ const dreaming = {
430
+ enabled: rawDreaming.enabled === true,
431
+ journalPath: typeof rawDreaming.journalPath === "string" && rawDreaming.journalPath.trim().length > 0 ? rawDreaming.journalPath.trim() : "DREAMS.md",
432
+ maxEntries: typeof rawDreaming.maxEntries === "number" ? rawDreaming.maxEntries === 0 ? 0 : rawDreaming.maxEntries < 0 ? 500 : rawDreaming.maxEntries < 10 ? 500 : Math.min(1e4, Math.floor(rawDreaming.maxEntries)) : 500,
433
+ injectRecentCount: typeof rawDreaming.injectRecentCount === "number" ? Math.min(20, Math.max(0, Math.floor(rawDreaming.injectRecentCount))) : 3,
434
+ minIntervalMinutes: typeof rawDreaming.minIntervalMinutes === "number" ? Math.max(1, Math.floor(rawDreaming.minIntervalMinutes)) : 120,
435
+ narrativeModel: typeof rawDreaming.narrativeModel === "string" && rawDreaming.narrativeModel.trim().length > 0 ? rawDreaming.narrativeModel.trim() : null,
436
+ narrativePromptStyle: rawDreaming.narrativePromptStyle === "diary" || rawDreaming.narrativePromptStyle === "analytical" ? rawDreaming.narrativePromptStyle : "reflective",
437
+ watchFile: rawDreaming.watchFile !== false
438
+ };
439
+ const rawDreamsBlock = cfg.dreams && typeof cfg.dreams === "object" && !Array.isArray(cfg.dreams) ? cfg.dreams : {};
440
+ const rawDreamsPhases = rawDreamsBlock.phases && typeof rawDreamsBlock.phases === "object" && !Array.isArray(rawDreamsBlock.phases) ? rawDreamsBlock.phases : {};
441
+ const rawDreamsLightSleep = rawDreamsPhases.lightSleep && typeof rawDreamsPhases.lightSleep === "object" && !Array.isArray(rawDreamsPhases.lightSleep) ? rawDreamsPhases.lightSleep : {};
442
+ const rawDreamsRem = rawDreamsPhases.rem && typeof rawDreamsPhases.rem === "object" && !Array.isArray(rawDreamsPhases.rem) ? rawDreamsPhases.rem : {};
443
+ const rawDreamsDeepSleep = rawDreamsPhases.deepSleep && typeof rawDreamsPhases.deepSleep === "object" && !Array.isArray(rawDreamsPhases.deepSleep) ? rawDreamsPhases.deepSleep : {};
444
+ const legacyLifecyclePolicyEnabled = coerceBooleanLike(cfg.lifecyclePolicyEnabled) ?? true;
445
+ const legacyLifecyclePromoteHeatThreshold = typeof cfg.lifecyclePromoteHeatThreshold === "number" ? Math.min(1, Math.max(0, cfg.lifecyclePromoteHeatThreshold)) : 0.55;
446
+ const legacyLifecycleStaleDecayThreshold = typeof cfg.lifecycleStaleDecayThreshold === "number" ? Math.min(1, Math.max(0, cfg.lifecycleStaleDecayThreshold)) : 0.65;
447
+ const legacyLifecycleArchiveDecayThreshold = typeof cfg.lifecycleArchiveDecayThreshold === "number" ? Math.min(1, Math.max(0, cfg.lifecycleArchiveDecayThreshold)) : 0.85;
448
+ const legacySemanticConsolidationEnabled = cfg.semanticConsolidationEnabled === true;
449
+ const legacySemanticConsolidationIntervalHours = typeof cfg.semanticConsolidationIntervalHours === "number" ? Math.max(1, Math.floor(cfg.semanticConsolidationIntervalHours)) : 168;
450
+ const legacySemanticConsolidationThreshold = typeof cfg.semanticConsolidationThreshold === "number" ? cfg.semanticConsolidationThreshold : 0.8;
451
+ const legacySemanticConsolidationMinClusterSize = typeof cfg.semanticConsolidationMinClusterSize === "number" ? Math.max(2, Math.floor(cfg.semanticConsolidationMinClusterSize)) : 3;
452
+ const legacySemanticConsolidationMaxPerRun = typeof cfg.semanticConsolidationMaxPerRun === "number" ? Math.max(0, Math.floor(cfg.semanticConsolidationMaxPerRun)) : 100;
453
+ const legacyConsolidationMinIntervalMs = typeof cfg.consolidationMinIntervalMs === "number" ? cfg.consolidationMinIntervalMs : 10 * 6e4;
454
+ const legacyVersioningEnabled = cfg.versioningEnabled === true;
455
+ const legacyVersioningMaxPerPage = typeof cfg.versioningMaxPerPage === "number" ? Math.max(0, Math.floor(cfg.versioningMaxPerPage)) : 50;
456
+ const legacyDeepSleepEnabled = cfg.nightlyGovernanceCronAutoRegister === true || cfg.qmdTierMigrationEnabled === true || legacyVersioningEnabled;
457
+ const dreamsLightSleepEnabledRaw = coerceBooleanLike(rawDreamsLightSleep.enabled);
458
+ const dreamsLightSleep = {
459
+ // new key wins; fall back to resolved legacy default
460
+ enabled: dreamsLightSleepEnabledRaw !== void 0 ? dreamsLightSleepEnabledRaw : legacyLifecyclePolicyEnabled,
461
+ cadenceMs: typeof rawDreamsLightSleep.cadenceMs === "number" ? Math.max(0, Math.floor(rawDreamsLightSleep.cadenceMs)) : 0,
462
+ // 0 = no override; orchestrator uses its own internal cadence
463
+ promoteHeatThreshold: typeof rawDreamsLightSleep.promoteHeatThreshold === "number" ? Math.min(1, Math.max(0, rawDreamsLightSleep.promoteHeatThreshold)) : legacyLifecyclePromoteHeatThreshold,
464
+ staleDecayThreshold: typeof rawDreamsLightSleep.staleDecayThreshold === "number" ? Math.min(1, Math.max(0, rawDreamsLightSleep.staleDecayThreshold)) : legacyLifecycleStaleDecayThreshold,
465
+ archiveDecayThreshold: typeof rawDreamsLightSleep.archiveDecayThreshold === "number" ? Math.min(1, Math.max(0, rawDreamsLightSleep.archiveDecayThreshold)) : legacyLifecycleArchiveDecayThreshold,
466
+ filterStaleEnabled: rawDreamsLightSleep.filterStaleEnabled !== void 0 ? coerceBooleanLike(rawDreamsLightSleep.filterStaleEnabled) === true : cfg.lifecycleFilterStaleEnabled === true
467
+ };
468
+ const dreamsRemEnabledRaw = coerceBooleanLike(rawDreamsRem.enabled);
469
+ const dreamsRem = {
470
+ enabled: dreamsRemEnabledRaw !== void 0 ? dreamsRemEnabledRaw : legacySemanticConsolidationEnabled,
471
+ cadenceMs: typeof rawDreamsRem.cadenceMs === "number" ? Math.max(0, Math.floor(rawDreamsRem.cadenceMs)) : legacySemanticConsolidationIntervalHours * 36e5,
472
+ similarityThreshold: typeof rawDreamsRem.similarityThreshold === "number" ? Math.min(1, Math.max(0, rawDreamsRem.similarityThreshold)) : legacySemanticConsolidationThreshold,
473
+ minClusterSize: typeof rawDreamsRem.minClusterSize === "number" ? Math.max(2, Math.floor(rawDreamsRem.minClusterSize)) : legacySemanticConsolidationMinClusterSize,
474
+ maxPerRun: typeof rawDreamsRem.maxPerRun === "number" ? Math.max(0, Math.floor(rawDreamsRem.maxPerRun)) : legacySemanticConsolidationMaxPerRun,
475
+ minIntervalMs: typeof rawDreamsRem.minIntervalMs === "number" ? Math.max(0, Math.floor(rawDreamsRem.minIntervalMs)) : legacyConsolidationMinIntervalMs
476
+ };
477
+ const dreamsDeepSleepEnabledRaw = coerceBooleanLike(rawDreamsDeepSleep.enabled);
478
+ const dreamsDeepSleep = {
479
+ enabled: dreamsDeepSleepEnabledRaw !== void 0 ? dreamsDeepSleepEnabledRaw : legacyDeepSleepEnabled,
480
+ enabledExplicitlySet: dreamsDeepSleepEnabledRaw !== void 0,
481
+ cadenceMs: typeof rawDreamsDeepSleep.cadenceMs === "number" ? Math.max(0, Math.floor(rawDreamsDeepSleep.cadenceMs)) : 24 * 36e5,
482
+ // default: 24 h (mirrors nightly governance cron)
483
+ versioningEnabled: rawDreamsDeepSleep.versioningEnabled !== void 0 ? coerceBooleanLike(rawDreamsDeepSleep.versioningEnabled) === true : legacyVersioningEnabled,
484
+ versioningMaxPerPage: typeof rawDreamsDeepSleep.versioningMaxPerPage === "number" ? Math.max(0, Math.floor(rawDreamsDeepSleep.versioningMaxPerPage)) : legacyVersioningMaxPerPage
485
+ };
486
+ const dreamsPhases = {
487
+ lightSleep: dreamsLightSleep,
488
+ rem: dreamsRem,
489
+ deepSleep: dreamsDeepSleep
490
+ };
491
+ const rawHeartbeat = cfg.heartbeat && typeof cfg.heartbeat === "object" && !Array.isArray(cfg.heartbeat) ? cfg.heartbeat : {};
492
+ const heartbeat = {
493
+ enabled: rawHeartbeat.enabled === true,
494
+ journalPath: typeof rawHeartbeat.journalPath === "string" && rawHeartbeat.journalPath.trim().length > 0 ? rawHeartbeat.journalPath.trim() : "HEARTBEAT.md",
495
+ maxPreviousRuns: typeof rawHeartbeat.maxPreviousRuns === "number" ? Math.min(20, Math.max(0, Math.floor(rawHeartbeat.maxPreviousRuns))) : 5,
496
+ watchFile: rawHeartbeat.watchFile !== false,
497
+ detectionMode: rawHeartbeat.detectionMode === "runtime-signal" || rawHeartbeat.detectionMode === "heuristic" ? rawHeartbeat.detectionMode : "auto",
498
+ gateExtractionDuringHeartbeat: rawHeartbeat.gateExtractionDuringHeartbeat !== false
499
+ };
500
+ const rawCodexCompat = cfg.codexCompat && typeof cfg.codexCompat === "object" && !Array.isArray(cfg.codexCompat) ? cfg.codexCompat : {};
501
+ const codexCompat = {
502
+ enabled: rawCodexCompat.enabled === true,
503
+ threadIdBufferKeying: rawCodexCompat.threadIdBufferKeying !== false,
504
+ compactionFlushMode: typeof rawCodexCompat.compactionFlushMode === "string" && VALID_CODEX_COMPACTION_FLUSH_MODES.includes(
505
+ rawCodexCompat.compactionFlushMode
506
+ ) ? rawCodexCompat.compactionFlushMode : "auto",
507
+ fingerprintDedup: rawCodexCompat.fingerprintDedup !== false
508
+ };
509
+ if (cfg.procedural !== void 0 && (cfg.procedural === null || typeof cfg.procedural !== "object" || Array.isArray(cfg.procedural))) {
510
+ throw new Error(
511
+ `procedural must be an object (got ${JSON.stringify(cfg.procedural)}). Use procedural: { enabled: false } to opt out; omit the key to use the default-on behavior (issue #567 PR 4).`
512
+ );
513
+ }
514
+ const rawProcedural = cfg.procedural && typeof cfg.procedural === "object" && !Array.isArray(cfg.procedural) ? cfg.procedural : {};
515
+ const proceduralMinCoerced = coerceNumber(rawProcedural.minOccurrences);
516
+ const proceduralMinRaw = proceduralMinCoerced !== void 0 ? Math.floor(proceduralMinCoerced) : 3;
517
+ const successFloorRaw = coerceNumber(rawProcedural.successFloor);
518
+ const successFloor = successFloorRaw !== void 0 && successFloorRaw >= 0 && successFloorRaw <= 1 ? successFloorRaw : 0.75;
519
+ const autoPromoteOccRaw = coerceNumber(rawProcedural.autoPromoteOccurrences);
520
+ const autoPromoteOccurrences = autoPromoteOccRaw !== void 0 && Number.isFinite(autoPromoteOccRaw) ? autoPromoteOccRaw <= 0 ? 0 : Math.min(1e4, Math.max(1, Math.floor(autoPromoteOccRaw))) : 8;
521
+ const lookbackCoerced = coerceNumber(rawProcedural.lookbackDays);
522
+ const lookbackDays = lookbackCoerced !== void 0 && Number.isFinite(lookbackCoerced) ? Math.min(3650, Math.max(1, Math.floor(lookbackCoerced))) : 14;
523
+ const recallMaxCoerced = coerceNumber(rawProcedural.recallMaxProcedures);
524
+ const recallMaxProcedures = recallMaxCoerced !== void 0 && Number.isFinite(recallMaxCoerced) ? Math.min(10, Math.max(1, Math.floor(recallMaxCoerced))) : 2;
525
+ const rawEnabledValue = rawProcedural.enabled;
526
+ let proceduralEnabled;
527
+ if (rawEnabledValue === void 0) {
528
+ proceduralEnabled = true;
529
+ } else {
530
+ const enabledCoerced = coerceBool(rawEnabledValue);
531
+ if (enabledCoerced === void 0) {
532
+ throw new Error(
533
+ `procedural.enabled must be a boolean or one of "true"/"false"/"1"/"0"/"yes"/"no"/"on"/"off" (got ${JSON.stringify(rawEnabledValue)}). Omit the key to use the default-on behavior (issue #567 PR 4).`
534
+ );
535
+ }
536
+ proceduralEnabled = enabledCoerced;
537
+ }
538
+ const procedural = {
539
+ enabled: proceduralEnabled,
540
+ /** `0` skips all mining (`minOccurrences_zero`); otherwise clusters need at least this many members. */
541
+ minOccurrences: Math.min(1e3, Math.max(0, proceduralMinRaw)),
542
+ successFloor,
543
+ autoPromoteOccurrences,
544
+ autoPromoteEnabled: coerceBool(rawProcedural.autoPromoteEnabled) === true,
545
+ lookbackDays,
546
+ proceduralMiningCronAutoRegister: coerceBool(rawProcedural.proceduralMiningCronAutoRegister) === true,
547
+ recallMaxProcedures
548
+ };
549
+ const rawCodingMode = cfg.codingMode && typeof cfg.codingMode === "object" && !Array.isArray(cfg.codingMode) ? cfg.codingMode : {};
550
+ const codingProjectScopeRaw = coerceBool(rawCodingMode.projectScope);
551
+ const codingBranchScopeRaw = coerceBool(rawCodingMode.branchScope);
552
+ const codingGlobalFallbackRaw = coerceBool(rawCodingMode.globalFallback);
553
+ const codingMode = {
554
+ projectScope: codingProjectScopeRaw === void 0 ? true : codingProjectScopeRaw,
555
+ branchScope: codingBranchScopeRaw === true,
556
+ // Default true — project-scoped sessions include the root namespace in
557
+ // read fallbacks so globally useful memories remain visible. CLAUDE.md #30.
558
+ globalFallback: codingGlobalFallbackRaw === void 0 ? true : codingGlobalFallbackRaw
559
+ };
560
+ const memoryDir = typeof cfg.memoryDir === "string" && cfg.memoryDir.length > 0 ? cfg.memoryDir : DEFAULT_MEMORY_DIR;
561
+ const rawIdentityInjectionMode = cfg.identityInjectionMode;
562
+ const identityInjectionMode = rawIdentityInjectionMode && VALID_IDENTITY_INJECTION_MODES.includes(rawIdentityInjectionMode) ? rawIdentityInjectionMode : "recovery_only";
563
+ const identityContinuityEnabled = cfg.identityContinuityEnabled === true;
564
+ const sessionObserverBands = Array.isArray(cfg.sessionObserverBands) ? cfg.sessionObserverBands.map((band) => ({
565
+ maxBytes: typeof band?.maxBytes === "number" ? Math.max(0, Math.floor(band.maxBytes)) : 0,
566
+ triggerDeltaBytes: typeof band?.triggerDeltaBytes === "number" ? Math.max(0, Math.floor(band.triggerDeltaBytes)) : 0,
567
+ triggerDeltaTokens: typeof band?.triggerDeltaTokens === "number" ? Math.max(0, Math.floor(band.triggerDeltaTokens)) : 0
568
+ })).filter((band) => band.maxBytes > 0) : cloneDefaultSessionObserverBands();
569
+ const principalRules = Array.isArray(cfg.principalFromSessionKeyRules) ? cfg.principalFromSessionKeyRules.map((r) => ({
570
+ match: typeof r?.match === "string" ? r.match : "",
571
+ principal: typeof r?.principal === "string" ? r.principal : ""
572
+ })).filter((r) => r.match.length > 0 && r.principal.length > 0) : [];
573
+ const entitySchemas = normalizeEntitySchemas(cfg.entitySchemas);
574
+ const rawHygiene = cfg.fileHygiene && typeof cfg.fileHygiene === "object" && !Array.isArray(cfg.fileHygiene) ? cfg.fileHygiene : void 0;
575
+ const hygieneEnabled = rawHygiene?.enabled === true;
576
+ const fileHygiene = hygieneEnabled ? {
577
+ enabled: true,
578
+ lintEnabled: rawHygiene?.lintEnabled !== false,
579
+ lintBudgetBytes: typeof rawHygiene?.lintBudgetBytes === "number" ? rawHygiene.lintBudgetBytes : 2e4,
580
+ lintWarnRatio: typeof rawHygiene?.lintWarnRatio === "number" ? rawHygiene.lintWarnRatio : 0.8,
581
+ lintPaths: Array.isArray(rawHygiene?.lintPaths) ? rawHygiene.lintPaths : ["IDENTITY.md", "MEMORY.md"],
582
+ rotateEnabled: rawHygiene?.rotateEnabled === true,
583
+ rotateMaxBytes: typeof rawHygiene?.rotateMaxBytes === "number" ? rawHygiene.rotateMaxBytes : 18e3,
584
+ rotateKeepTailChars: typeof rawHygiene?.rotateKeepTailChars === "number" ? rawHygiene.rotateKeepTailChars : 2e3,
585
+ rotatePaths: Array.isArray(rawHygiene?.rotatePaths) ? rawHygiene.rotatePaths : ["IDENTITY.md"],
586
+ archiveDir: typeof rawHygiene?.archiveDir === "string" && rawHygiene.archiveDir.length > 0 ? rawHygiene.archiveDir : ".engram-archive",
587
+ runMinIntervalMs: typeof rawHygiene?.runMinIntervalMs === "number" ? rawHygiene.runMinIntervalMs : 5 * 60 * 1e3,
588
+ warningsLogEnabled: rawHygiene?.warningsLogEnabled === true,
589
+ warningsLogPath: typeof rawHygiene?.warningsLogPath === "string" && rawHygiene.warningsLogPath.length > 0 ? rawHygiene.warningsLogPath : "hygiene/warnings.md",
590
+ indexEnabled: rawHygiene?.indexEnabled === true,
591
+ indexPath: typeof rawHygiene?.indexPath === "string" && rawHygiene.indexPath.length > 0 ? rawHygiene.indexPath : "ENGRAM_INDEX.md"
592
+ } : void 0;
593
+ const rawNativeKnowledge = cfg.nativeKnowledge && typeof cfg.nativeKnowledge === "object" && !Array.isArray(cfg.nativeKnowledge) ? cfg.nativeKnowledge : void 0;
594
+ const nativeKnowledge = rawNativeKnowledge?.enabled === true ? {
595
+ enabled: true,
596
+ includeFiles: Array.isArray(rawNativeKnowledge.includeFiles) ? rawNativeKnowledge.includeFiles.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : ["IDENTITY.md", "MEMORY.md"],
597
+ maxChunkChars: typeof rawNativeKnowledge.maxChunkChars === "number" ? Math.max(200, Math.floor(rawNativeKnowledge.maxChunkChars)) : 900,
598
+ maxResults: typeof rawNativeKnowledge.maxResults === "number" ? Math.max(0, Math.floor(rawNativeKnowledge.maxResults)) : 4,
599
+ maxChars: typeof rawNativeKnowledge.maxChars === "number" ? Math.max(0, Math.floor(rawNativeKnowledge.maxChars)) : 2400,
600
+ stateDir: normalizeMemoryRelativeDir(rawNativeKnowledge.stateDir, "state/native-knowledge"),
601
+ openclawWorkspace: rawNativeKnowledge.openclawWorkspace && typeof rawNativeKnowledge.openclawWorkspace === "object" && !Array.isArray(rawNativeKnowledge.openclawWorkspace) && rawNativeKnowledge.openclawWorkspace.enabled === true ? {
602
+ enabled: true,
603
+ bootstrapFiles: Array.isArray(rawNativeKnowledge.openclawWorkspace.bootstrapFiles) ? rawNativeKnowledge.openclawWorkspace.bootstrapFiles.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : ["IDENTITY.md", "MEMORY.md", "USER.md"],
604
+ handoffGlobs: Array.isArray(rawNativeKnowledge.openclawWorkspace.handoffGlobs) ? rawNativeKnowledge.openclawWorkspace.handoffGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : ["**/*handoff*.md", "handoffs/**/*.md"],
605
+ dailySummaryGlobs: Array.isArray(rawNativeKnowledge.openclawWorkspace.dailySummaryGlobs) ? rawNativeKnowledge.openclawWorkspace.dailySummaryGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : ["**/*daily*summary*.md", "summaries/**/*.md"],
606
+ automationNoteGlobs: Array.isArray(rawNativeKnowledge.openclawWorkspace.automationNoteGlobs) ? rawNativeKnowledge.openclawWorkspace.automationNoteGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : [],
607
+ workspaceDocGlobs: Array.isArray(rawNativeKnowledge.openclawWorkspace.workspaceDocGlobs) ? rawNativeKnowledge.openclawWorkspace.workspaceDocGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : [],
608
+ excludeGlobs: [
609
+ ".git/**",
610
+ "node_modules/**",
611
+ "dist/**",
612
+ "build/**",
613
+ "coverage/**",
614
+ "**/*.log",
615
+ "**/.env*",
616
+ "**/*.pem",
617
+ "**/*.key",
618
+ ...Array.isArray(rawNativeKnowledge.openclawWorkspace.excludeGlobs) ? rawNativeKnowledge.openclawWorkspace.excludeGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : []
619
+ ].filter((value, index, array) => array.indexOf(value) === index),
620
+ sharedSafeGlobs: Array.isArray(rawNativeKnowledge.openclawWorkspace.sharedSafeGlobs) ? rawNativeKnowledge.openclawWorkspace.sharedSafeGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : []
621
+ } : void 0,
622
+ obsidianVaults: Array.isArray(rawNativeKnowledge.obsidianVaults) ? rawNativeKnowledge.obsidianVaults.filter((value) => !!value && typeof value === "object" && !Array.isArray(value)).map((vault, index) => {
623
+ const defaultId = `vault-${index + 1}`;
624
+ return {
625
+ id: typeof vault.id === "string" && vault.id.trim().length > 0 ? vault.id.trim() : defaultId,
626
+ rootDir: typeof vault.rootDir === "string" && vault.rootDir.trim().length > 0 ? vault.rootDir.trim() : "",
627
+ includeGlobs: Array.isArray(vault.includeGlobs) ? vault.includeGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : ["**/*.md"],
628
+ excludeGlobs: Array.isArray(vault.excludeGlobs) ? vault.excludeGlobs.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : [".obsidian/**", "**/*.canvas", "**/*.png", "**/*.jpg", "**/*.jpeg", "**/*.gif", "**/*.pdf"],
629
+ namespace: typeof vault.namespace === "string" && vault.namespace.trim().length > 0 ? vault.namespace.trim() : void 0,
630
+ privacyClass: typeof vault.privacyClass === "string" && vault.privacyClass.trim().length > 0 ? vault.privacyClass.trim() : void 0,
631
+ folderRules: Array.isArray(vault.folderRules) ? vault.folderRules.filter((value) => !!value && typeof value === "object" && !Array.isArray(value)).map((rule) => ({
632
+ pathPrefix: typeof rule.pathPrefix === "string" && rule.pathPrefix.trim().length > 0 ? rule.pathPrefix.trim() : "",
633
+ namespace: typeof rule.namespace === "string" && rule.namespace.trim().length > 0 ? rule.namespace.trim() : void 0,
634
+ privacyClass: typeof rule.privacyClass === "string" && rule.privacyClass.trim().length > 0 ? rule.privacyClass.trim() : void 0
635
+ })).filter((rule) => rule.pathPrefix.length > 0) : [],
636
+ dailyNotePatterns: Array.isArray(vault.dailyNotePatterns) ? vault.dailyNotePatterns.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean) : ["YYYY-MM-DD"],
637
+ materializeBacklinks: vault.materializeBacklinks === true
638
+ };
639
+ }).filter((vault) => vault.rootDir.length > 0) : []
640
+ } : void 0;
641
+ const rawAgentAccessHttp = cfg.agentAccessHttp && typeof cfg.agentAccessHttp === "object" && !Array.isArray(cfg.agentAccessHttp) ? cfg.agentAccessHttp : void 0;
642
+ const agentAccessAuthToken = parseAgentAccessAuthToken(rawAgentAccessHttp?.authToken);
643
+ const agentAccessHttp = {
644
+ enabled: rawAgentAccessHttp?.enabled === true,
645
+ host: typeof rawAgentAccessHttp?.host === "string" && rawAgentAccessHttp.host.trim().length > 0 ? rawAgentAccessHttp.host.trim() : "127.0.0.1",
646
+ port: typeof rawAgentAccessHttp?.port === "number" ? Math.max(0, Math.floor(rawAgentAccessHttp.port)) : 4318,
647
+ [["auth", "Token"].join("")]: agentAccessAuthToken,
648
+ principal: typeof rawAgentAccessHttp?.principal === "string" && rawAgentAccessHttp.principal.trim().length > 0 ? resolveEnvVars(rawAgentAccessHttp.principal) : readEnvVar("OPENCLAW_ENGRAM_ACCESS_PRINCIPAL")?.trim() || void 0,
649
+ maxBodyBytes: typeof rawAgentAccessHttp?.maxBodyBytes === "number" ? Math.max(1, Math.floor(rawAgentAccessHttp.maxBodyBytes)) : 131072
650
+ };
651
+ let baseUrl;
652
+ if (typeof cfg.openaiBaseUrl === "string" && cfg.openaiBaseUrl.length > 0) {
653
+ baseUrl = normalizeOpenaiBaseUrl(resolveEnvVars(cfg.openaiBaseUrl), "config");
654
+ } else {
655
+ baseUrl = normalizeOpenaiBaseUrl(readEnvVar("OPENAI_BASE_URL"), "env");
656
+ }
657
+ const sharedCrossSignalSemanticEnabled = cfg.sharedCrossSignalSemanticEnabled === true || cfg.crossSignalsSemanticEnabled === true;
658
+ const sharedCrossSignalSemanticTimeoutMs = typeof cfg.sharedCrossSignalSemanticTimeoutMs === "number" ? Math.max(1, Math.floor(cfg.sharedCrossSignalSemanticTimeoutMs)) : typeof cfg.crossSignalsSemanticTimeoutMs === "number" ? Math.max(1, Math.floor(cfg.crossSignalsSemanticTimeoutMs)) : 4e3;
659
+ const recallPipelineConfig = buildRecallPipelineConfig(cfg);
660
+ return {
661
+ openaiApiKey: apiKey,
662
+ openaiBaseUrl: baseUrl,
663
+ model,
664
+ reasoningEffort,
665
+ triggerMode,
666
+ bufferMaxTurns: typeof cfg.bufferMaxTurns === "number" ? cfg.bufferMaxTurns : 5,
667
+ bufferMaxMinutes: typeof cfg.bufferMaxMinutes === "number" ? cfg.bufferMaxMinutes : 15,
668
+ // Surprise-gated buffer flush (issue #563, D-MEM). See types.ts for
669
+ // semantics. Default off so PR 2 ships as a pure no-op until an operator
670
+ // opts in. PR 4 benchmarks the flag and may flip the default.
671
+ //
672
+ // Use `coerceBool` rather than a strict `=== true` check: CLI operators
673
+ // set booleans via `--config bufferSurpriseTriggerEnabled=true` which
674
+ // arrives as the string `"true"` — the strict form would silently
675
+ // leave the flag off. Matches the coercion contract established for
676
+ // other boolean config keys (CLAUDE.md rule #36).
677
+ bufferSurpriseTriggerEnabled: coerceBool(cfg.bufferSurpriseTriggerEnabled) === true,
678
+ // Numeric surprise knobs go through `coerceNumber` so CLI operators
679
+ // can pass `--config bufferSurpriseThreshold=0.5` without the string
680
+ // silently dropping to the default. Matches the coercion contract
681
+ // applied to other numeric config keys (CLAUDE.md rule #28).
682
+ bufferSurpriseThreshold: clampSurpriseThreshold(
683
+ coerceNumber(cfg.bufferSurpriseThreshold),
684
+ 0.35
685
+ ),
686
+ bufferSurpriseK: clampSurpriseK(
687
+ coerceNumber(cfg.bufferSurpriseK),
688
+ 5
689
+ ),
690
+ bufferSurpriseRecentMemoryCount: clampSurpriseRecentMemoryCount(
691
+ coerceNumber(cfg.bufferSurpriseRecentMemoryCount),
692
+ 20
693
+ ),
694
+ bufferSurpriseProbeTimeoutMs: clampSurpriseProbeTimeoutMs(
695
+ coerceNumber(cfg.bufferSurpriseProbeTimeoutMs),
696
+ 2e3
697
+ ),
698
+ consolidateEveryN: typeof cfg.consolidateEveryN === "number" ? cfg.consolidateEveryN : 3,
699
+ highSignalPatterns: Array.isArray(cfg.highSignalPatterns) ? cfg.highSignalPatterns : [],
700
+ maxMemoryTokens: typeof cfg.maxMemoryTokens === "number" ? cfg.maxMemoryTokens : 2e3,
701
+ memoryOsPreset,
702
+ qmdEnabled: cfg.qmdEnabled !== false,
703
+ qmdCollection: typeof cfg.qmdCollection === "string" ? cfg.qmdCollection : "openclaw-engram",
704
+ qmdMaxResults: typeof cfg.qmdMaxResults === "number" ? cfg.qmdMaxResults : 8,
705
+ qmdColdTierEnabled: cfg.qmdColdTierEnabled === true,
706
+ qmdColdCollection: typeof cfg.qmdColdCollection === "string" && cfg.qmdColdCollection.length > 0 ? cfg.qmdColdCollection : "openclaw-engram-cold",
707
+ qmdColdMaxResults: typeof cfg.qmdColdMaxResults === "number" ? cfg.qmdColdMaxResults : 8,
708
+ // Issue #678 PR 2/4: gate hot/cold tier migration (a deep-sleep activity)
709
+ // on dreams.phases.deepSleep.enabled. When deep sleep is disabled,
710
+ // tier migration is forced off regardless of legacy flag.
711
+ qmdTierMigrationEnabled: dreamsDeepSleep.enabled && cfg.qmdTierMigrationEnabled === true,
712
+ qmdTierDemotionMinAgeDays: typeof cfg.qmdTierDemotionMinAgeDays === "number" ? Math.max(0, Math.floor(cfg.qmdTierDemotionMinAgeDays)) : 14,
713
+ qmdTierDemotionValueThreshold: typeof cfg.qmdTierDemotionValueThreshold === "number" ? Math.max(0, Math.min(1, cfg.qmdTierDemotionValueThreshold)) : 0.35,
714
+ qmdTierPromotionValueThreshold: typeof cfg.qmdTierPromotionValueThreshold === "number" ? Math.max(0, Math.min(1, cfg.qmdTierPromotionValueThreshold)) : 0.7,
715
+ qmdTierParityGraphEnabled: cfg.qmdTierParityGraphEnabled !== false,
716
+ qmdTierParityHiMemEnabled: cfg.qmdTierParityHiMemEnabled !== false,
717
+ qmdTierAutoBackfillEnabled: cfg.qmdTierAutoBackfillEnabled === true,
718
+ qmdSupportedVersion: parseQmdSupportedVersion(cfg.qmdSupportedVersion),
719
+ qmdAutoUpgradeEnabled: coerceBool(cfg.qmdAutoUpgradeEnabled) === true,
720
+ qmdAutoUpgradeCheckIntervalMs: parseBoundedIntegerMs(
721
+ cfg.qmdAutoUpgradeCheckIntervalMs,
722
+ 24 * 60 * 6e4,
723
+ 6e4,
724
+ 30 * 24 * 60 * 6e4
725
+ ),
726
+ qmdChunkStrategy: parseQmdChunkStrategy(cfg.qmdChunkStrategy),
727
+ qmdCandidateLimit: parsePositiveInteger(cfg.qmdCandidateLimit, "qmdCandidateLimit"),
728
+ qmdQueryRerankEnabled: coerceBooleanLike(cfg.qmdQueryRerankEnabled) ?? true,
729
+ qmdIndexName: parseOptionalNonEmptyString(cfg.qmdIndexName),
730
+ qmdForceCpu: coerceBooleanLike(cfg.qmdForceCpu) ?? false,
731
+ qmdGpuBackend: parseQmdGpuBackend(cfg.qmdGpuBackend),
732
+ qmdEmbedParallelism: parseBoundedPositiveInteger(
733
+ cfg.qmdEmbedParallelism,
734
+ 1,
735
+ 8,
736
+ "qmdEmbedParallelism"
737
+ ),
738
+ qmdEmbedModel: parseOptionalNonEmptyString(cfg.qmdEmbedModel),
739
+ qmdRerankModel: parseOptionalNonEmptyString(cfg.qmdRerankModel),
740
+ qmdGenerateModel: parseOptionalNonEmptyString(cfg.qmdGenerateModel),
741
+ embeddingFallbackEnabled: cfg.embeddingFallbackEnabled !== false,
742
+ embeddingFallbackProvider: cfg.embeddingFallbackProvider === "openai" ? "openai" : cfg.embeddingFallbackProvider === "local" ? "local" : "auto",
743
+ embeddingFallbackModel: typeof cfg.embeddingFallbackModel === "string" && cfg.embeddingFallbackModel.length > 0 ? cfg.embeddingFallbackModel : "",
744
+ qmdPath: typeof cfg.qmdPath === "string" && cfg.qmdPath.length > 0 ? cfg.qmdPath : void 0,
745
+ memoryDir,
746
+ debug: cfg.debug === true,
747
+ identityEnabled: cfg.identityEnabled !== false,
748
+ identityContinuityEnabled,
749
+ identityInjectionMode,
750
+ identityMaxInjectChars: typeof cfg.identityMaxInjectChars === "number" ? Math.max(0, Math.floor(cfg.identityMaxInjectChars)) : 1200,
751
+ continuityIncidentLoggingEnabled: typeof cfg.continuityIncidentLoggingEnabled === "boolean" ? cfg.continuityIncidentLoggingEnabled : identityContinuityEnabled,
752
+ continuityAuditEnabled: cfg.continuityAuditEnabled === true,
753
+ sessionObserverEnabled: cfg.sessionObserverEnabled === true,
754
+ sessionObserverDebounceMs: typeof cfg.sessionObserverDebounceMs === "number" ? Math.max(0, Math.floor(cfg.sessionObserverDebounceMs)) : 12e4,
755
+ sessionObserverBands,
756
+ injectQuestions: cfg.injectQuestions === true,
757
+ commitmentDecayDays: parseIntegerAtLeast(
758
+ cfg.commitmentDecayDays,
759
+ 90,
760
+ 1,
761
+ "commitmentDecayDays"
762
+ ),
763
+ workspaceDir: typeof cfg.workspaceDir === "string" && cfg.workspaceDir.length > 0 ? cfg.workspaceDir : DEFAULT_WORKSPACE_DIR,
764
+ captureMode,
765
+ fileHygiene,
766
+ nativeKnowledge,
767
+ agentAccessHttp,
768
+ // Access tracking (Phase 1A)
769
+ accessTrackingEnabled: cfg.accessTrackingEnabled !== false,
770
+ accessTrackingBufferMaxSize: typeof cfg.accessTrackingBufferMaxSize === "number" ? cfg.accessTrackingBufferMaxSize : 100,
771
+ // Retrieval options
772
+ recencyWeight: typeof cfg.recencyWeight === "number" ? cfg.recencyWeight : 0.2,
773
+ boostAccessCount: cfg.boostAccessCount !== false,
774
+ recordEmptyRecallImpressions: cfg.recordEmptyRecallImpressions === true,
775
+ // v2.2 Advanced Retrieval (safe defaults: off unless enabled)
776
+ queryExpansionEnabled: cfg.queryExpansionEnabled === true,
777
+ queryExpansionMaxQueries: typeof cfg.queryExpansionMaxQueries === "number" ? cfg.queryExpansionMaxQueries : 4,
778
+ queryExpansionMinTokenLen: typeof cfg.queryExpansionMinTokenLen === "number" ? cfg.queryExpansionMinTokenLen : 3,
779
+ rerankEnabled: cfg.rerankEnabled === true,
780
+ rerankProvider: cfg.rerankProvider === "cloud" ? "cloud" : "local",
781
+ rerankMaxCandidates: typeof cfg.rerankMaxCandidates === "number" ? cfg.rerankMaxCandidates : 20,
782
+ rerankTimeoutMs: typeof cfg.rerankTimeoutMs === "number" ? cfg.rerankTimeoutMs : 8e3,
783
+ rerankCacheEnabled: cfg.rerankCacheEnabled !== false,
784
+ rerankCacheTtlMs: typeof cfg.rerankCacheTtlMs === "number" ? cfg.rerankCacheTtlMs : 60 * 60 * 1e3,
785
+ feedbackEnabled: cfg.feedbackEnabled === true,
786
+ // v2.2 Negative Examples (safe defaults: off unless enabled)
787
+ negativeExamplesEnabled: cfg.negativeExamplesEnabled === true,
788
+ negativeExamplesPenaltyPerHit: typeof cfg.negativeExamplesPenaltyPerHit === "number" ? cfg.negativeExamplesPenaltyPerHit : 0.05,
789
+ negativeExamplesPenaltyCap: typeof cfg.negativeExamplesPenaltyCap === "number" ? cfg.negativeExamplesPenaltyCap : 0.25,
790
+ // Chunking (Phase 2A)
791
+ chunkingEnabled: cfg.chunkingEnabled === true,
792
+ // Off by default initially
793
+ chunkingTargetTokens: typeof cfg.chunkingTargetTokens === "number" ? cfg.chunkingTargetTokens : 200,
794
+ chunkingMinTokens: typeof cfg.chunkingMinTokens === "number" ? cfg.chunkingMinTokens : 150,
795
+ chunkingOverlapSentences: typeof cfg.chunkingOverlapSentences === "number" ? cfg.chunkingOverlapSentences : 2,
796
+ // Semantic Chunking (Issue #368)
797
+ semanticChunkingEnabled: cfg.semanticChunkingEnabled === true,
798
+ semanticChunkingConfig: parseSemanticChunkingConfig(cfg.semanticChunkingConfig),
799
+ // Contradiction Detection (Phase 2B)
800
+ contradictionDetectionEnabled: cfg.contradictionDetectionEnabled === true,
801
+ // Off by default initially
802
+ contradictionSimilarityThreshold: typeof cfg.contradictionSimilarityThreshold === "number" ? cfg.contradictionSimilarityThreshold : 0.7,
803
+ contradictionMinConfidence: typeof cfg.contradictionMinConfidence === "number" ? cfg.contradictionMinConfidence : 0.9,
804
+ contradictionAutoResolve: cfg.contradictionAutoResolve !== false,
805
+ // Contradiction Scan cron (issue #520)
806
+ contradictionScan: parseContradictionScanConfig(cfg.contradictionScan),
807
+ // Temporal Supersession (issue #375)
808
+ temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false,
809
+ // On by default
810
+ temporalSupersessionIncludeInRecall: cfg.temporalSupersessionIncludeInRecall === true,
811
+ // Off by default
812
+ // Direct-answer retrieval tier (issue #518). Default on — the
813
+ // tier runs in observation mode: it annotates
814
+ // LastRecallSnapshot.tierExplain but never short-circuits the
815
+ // QMD path. Operators can opt out with
816
+ // recallDirectAnswerEnabled=false.
817
+ recallDirectAnswerEnabled: coerceBool(cfg.recallDirectAnswerEnabled) ?? true,
818
+ // Disclosure auto-escalation (issue #677 PR 4/4). Default `manual`
819
+ // so pre-#677 callers see unchanged behavior. Reject anything
820
+ // outside the allow-list rather than silently defaulting (CLAUDE.md
821
+ // rule 51).
822
+ recallDisclosureEscalation: (() => {
823
+ const raw2 = cfg.recallDisclosureEscalation;
824
+ if (raw2 === void 0 || raw2 === null) return "manual";
825
+ if (raw2 === "manual" || raw2 === "auto") return raw2;
826
+ throw new Error(
827
+ `recallDisclosureEscalation must be "manual" or "auto" (got ${JSON.stringify(raw2)}).`
828
+ );
829
+ })(),
830
+ recallDisclosureEscalationThreshold: (() => {
831
+ const n = coerceNumber(cfg.recallDisclosureEscalationThreshold);
832
+ return n !== void 0 && n >= 0 && n <= 1 ? n : 0.5;
833
+ })(),
834
+ // Graph-based retrieval tier (issue #559 PR 4). Default `false` —
835
+ // the tier ships off pending the `retrieval-graph` bench in PR 5.
836
+ recallGraphEnabled: coerceBool(cfg.recallGraphEnabled) ?? false,
837
+ recallGraphDamping: (() => {
838
+ const n = coerceNumber(cfg.recallGraphDamping);
839
+ return n !== void 0 && n >= 0 && n < 1 ? n : 0.85;
840
+ })(),
841
+ // Fractional integer values (e.g. `0.5`) are REJECTED rather than
842
+ // silently floored to zero — CLAUDE.md rule 51 ("Reject invalid
843
+ // user input instead of silently defaulting"). Users who set a
844
+ // fractional iteration cap almost certainly meant an integer and
845
+ // quietly flooring their value to 0 turns off the tier without
846
+ // warning.
847
+ recallGraphIterations: (() => {
848
+ if (cfg.recallGraphIterations === void 0) return 20;
849
+ const n = coerceNumber(cfg.recallGraphIterations);
850
+ if (n === void 0 || !Number.isFinite(n) || n < 0 || n > 500) {
851
+ throw new Error(
852
+ `recallGraphIterations must be an integer in [0, 500] (got ${JSON.stringify(cfg.recallGraphIterations)}).`
853
+ );
854
+ }
855
+ if (!Number.isInteger(n)) {
856
+ throw new Error(
857
+ `recallGraphIterations must be an integer (got fractional value ${n}).`
858
+ );
859
+ }
860
+ return n;
861
+ })(),
862
+ recallGraphTopK: (() => {
863
+ if (cfg.recallGraphTopK === void 0) return 50;
864
+ const n = coerceNumber(cfg.recallGraphTopK);
865
+ if (n === void 0 || !Number.isFinite(n) || n < 0 || n > 1e4) {
866
+ throw new Error(
867
+ `recallGraphTopK must be an integer in [0, 10000] (got ${JSON.stringify(cfg.recallGraphTopK)}).`
868
+ );
869
+ }
870
+ if (!Number.isInteger(n)) {
871
+ throw new Error(
872
+ `recallGraphTopK must be an integer (got fractional value ${n}).`
873
+ );
874
+ }
875
+ return n;
876
+ })(),
877
+ recallDirectAnswerTokenOverlapFloor: (() => {
878
+ const n = coerceNumber(cfg.recallDirectAnswerTokenOverlapFloor);
879
+ return n !== void 0 && n >= 0 && n <= 1 ? n : 0.55;
880
+ })(),
881
+ recallDirectAnswerImportanceFloor: (() => {
882
+ const n = coerceNumber(cfg.recallDirectAnswerImportanceFloor);
883
+ return n !== void 0 && n >= 0 && n <= 1 ? n : 0.7;
884
+ })(),
885
+ recallDirectAnswerAmbiguityMargin: (() => {
886
+ const n = coerceNumber(cfg.recallDirectAnswerAmbiguityMargin);
887
+ return n !== void 0 && n >= 0 && n <= 1 ? n : 0.15;
888
+ })(),
889
+ recallDirectAnswerEligibleTaxonomyBuckets: Array.isArray(
890
+ cfg.recallDirectAnswerEligibleTaxonomyBuckets
891
+ ) ? cfg.recallDirectAnswerEligibleTaxonomyBuckets.filter(
892
+ (v) => typeof v === "string" && v.length > 0
893
+ ) : ["decisions", "principles", "conventions", "runbooks", "entities"],
894
+ // Cross-namespace query-budget limiter (issue #565 PR 4/5).
895
+ // Defaults to false — ships disabled so existing deployments are
896
+ // unaffected. When enabled, the read path throttles a principal that
897
+ // issues a burst of recalls against namespaces other than their own.
898
+ recallCrossNamespaceBudgetEnabled: coerceBool(cfg.recallCrossNamespaceBudgetEnabled) ?? false,
899
+ recallCrossNamespaceBudgetWindowMs: (() => {
900
+ const n = coerceNumber(cfg.recallCrossNamespaceBudgetWindowMs);
901
+ return n !== void 0 && n > 0 ? Math.floor(n) : 6e4;
902
+ })(),
903
+ recallCrossNamespaceBudgetSoftLimit: (() => {
904
+ const n = coerceNumber(cfg.recallCrossNamespaceBudgetSoftLimit);
905
+ return n !== void 0 && n >= 0 ? Math.floor(n) : 10;
906
+ })(),
907
+ recallCrossNamespaceBudgetHardLimit: (() => {
908
+ const n = coerceNumber(cfg.recallCrossNamespaceBudgetHardLimit);
909
+ return n !== void 0 && n > 0 ? Math.floor(n) : 30;
910
+ })(),
911
+ // Recall-audit anomaly detector (issue #565 PR 5/5). Defaults off so
912
+ // existing deployments are unaffected; enable explicitly to let the
913
+ // access surfaces flag suspicious query patterns derived from the
914
+ // audit trail. Thresholds floor AFTER validating the floored value
915
+ // is still >= 1 — a `0.5` input that floors to 0 would turn every
916
+ // detector into a flood-on-anything, flipping the default to
917
+ // max-noise instead of max-silence.
918
+ recallAuditAnomalyDetectionEnabled: coerceBool(cfg.recallAuditAnomalyDetectionEnabled) ?? false,
919
+ recallAuditAnomalyWindowMs: (() => {
920
+ const n = coerceNumber(cfg.recallAuditAnomalyWindowMs);
921
+ if (n === void 0) return 5 * 6e4;
922
+ const floored = Math.floor(n);
923
+ return floored >= 1 ? floored : 5 * 6e4;
924
+ })(),
925
+ recallAuditAnomalyRepeatQueryLimit: (() => {
926
+ const n = coerceNumber(cfg.recallAuditAnomalyRepeatQueryLimit);
927
+ if (n === void 0) return 5;
928
+ const floored = Math.floor(n);
929
+ return floored >= 1 ? floored : 5;
930
+ })(),
931
+ recallAuditAnomalyNamespaceWalkLimit: (() => {
932
+ const n = coerceNumber(cfg.recallAuditAnomalyNamespaceWalkLimit);
933
+ if (n === void 0) return 3;
934
+ const floored = Math.floor(n);
935
+ return floored >= 1 ? floored : 3;
936
+ })(),
937
+ recallAuditAnomalyHighCardinalityLimit: (() => {
938
+ const n = coerceNumber(cfg.recallAuditAnomalyHighCardinalityLimit);
939
+ if (n === void 0) return 50;
940
+ const floored = Math.floor(n);
941
+ return floored >= 1 ? floored : 50;
942
+ })(),
943
+ recallAuditAnomalyRapidFireLimit: (() => {
944
+ const n = coerceNumber(cfg.recallAuditAnomalyRapidFireLimit);
945
+ if (n === void 0) return 30;
946
+ const floored = Math.floor(n);
947
+ return floored >= 1 ? floored : 30;
948
+ })(),
949
+ // Memory Worth recall filter (issue #560 PR 4, default flipped in PR 5).
950
+ // Bench result on the seeded fixture: precision@5 lifts from 0.00 to
951
+ // 0.60 across all 50 cases with zero regressions. See
952
+ // `runMemoryWorthBench` in memory-worth-bench.ts. Operators can still
953
+ // opt out with recallMemoryWorthFilterEnabled=false.
954
+ recallMemoryWorthFilterEnabled: coerceBool(cfg.recallMemoryWorthFilterEnabled) ?? true,
955
+ recallMemoryWorthHalfLifeMs: (() => {
956
+ const n = coerceNumber(cfg.recallMemoryWorthHalfLifeMs);
957
+ return n !== void 0 && n >= 0 ? n : 0;
958
+ })(),
959
+ // Memory Linking (Phase 3A)
960
+ memoryLinkingEnabled: cfg.memoryLinkingEnabled === true,
961
+ // Off by default initially
962
+ // Conversation Threading (Phase 3B)
963
+ threadingEnabled: cfg.threadingEnabled === true,
964
+ // Off by default initially
965
+ threadingGapMinutes: typeof cfg.threadingGapMinutes === "number" ? cfg.threadingGapMinutes : 30,
966
+ // Memory Summarization (Phase 4A)
967
+ summarizationEnabled: cfg.summarizationEnabled === true,
968
+ // Off by default
969
+ summarizationTriggerCount: typeof cfg.summarizationTriggerCount === "number" ? cfg.summarizationTriggerCount : 1e3,
970
+ summarizationRecentToKeep: typeof cfg.summarizationRecentToKeep === "number" ? cfg.summarizationRecentToKeep : 300,
971
+ summarizationImportanceThreshold: typeof cfg.summarizationImportanceThreshold === "number" ? cfg.summarizationImportanceThreshold : 0.3,
972
+ summarizationProtectedTags: Array.isArray(cfg.summarizationProtectedTags) ? cfg.summarizationProtectedTags : ["commitment", "preference", "decision", "principle"],
973
+ // Topic Extraction (Phase 4B)
974
+ topicExtractionEnabled: cfg.topicExtractionEnabled !== false,
975
+ // On by default
976
+ topicExtractionTopN: typeof cfg.topicExtractionTopN === "number" ? cfg.topicExtractionTopN : 50,
977
+ // Transcript & Context Preservation (v2.0)
978
+ // Transcript archive
979
+ transcriptEnabled: cfg.transcriptEnabled !== false,
980
+ // default: true
981
+ transcriptRetentionDays: typeof cfg.transcriptRetentionDays === "number" ? cfg.transcriptRetentionDays : 7,
982
+ transcriptSkipChannelTypes: Array.isArray(cfg.transcriptSkipChannelTypes) ? cfg.transcriptSkipChannelTypes : ["cron"],
983
+ // default: skip cron transcripts
984
+ // Transcript injection
985
+ transcriptRecallHours: typeof cfg.transcriptRecallHours === "number" ? cfg.transcriptRecallHours : 12,
986
+ maxTranscriptTurns: typeof cfg.maxTranscriptTurns === "number" ? cfg.maxTranscriptTurns : 50,
987
+ maxTranscriptTokens: typeof cfg.maxTranscriptTokens === "number" ? cfg.maxTranscriptTokens : 1e3,
988
+ // Checkpoint
989
+ checkpointEnabled: cfg.checkpointEnabled !== false,
990
+ // default: true
991
+ checkpointTurns: typeof cfg.checkpointTurns === "number" ? cfg.checkpointTurns : 15,
992
+ // Compaction reset (opt-in, default: false)
993
+ compactionResetEnabled: cfg.compactionResetEnabled === true,
994
+ beforeResetTimeoutMs: typeof cfg.beforeResetTimeoutMs === "number" ? Math.min(3e4, Math.max(100, Math.floor(cfg.beforeResetTimeoutMs))) : 2e3,
995
+ initGateTimeoutMs: parseBoundedIntegerMs(
996
+ cfg.initGateTimeoutMs,
997
+ DEFAULT_INIT_GATE_TIMEOUT_MS,
998
+ 1e3,
999
+ 12e4
1000
+ ),
1001
+ flushOnResetEnabled: cfg.flushOnResetEnabled !== false,
1002
+ commandsListEnabled: cfg.commandsListEnabled !== false,
1003
+ openclawToolsEnabled: cfg.openclawToolsEnabled !== false,
1004
+ openclawToolSnippetMaxChars: typeof cfg.openclawToolSnippetMaxChars === "number" ? Math.min(4e3, Math.max(80, Math.floor(cfg.openclawToolSnippetMaxChars))) : 600,
1005
+ sessionTogglesEnabled: cfg.sessionTogglesEnabled !== false,
1006
+ verboseRecallVisibility: cfg.verboseRecallVisibility !== false,
1007
+ recallTranscriptsEnabled: cfg.recallTranscriptsEnabled === true,
1008
+ recallTranscriptRetentionDays: typeof cfg.recallTranscriptRetentionDays === "number" ? Math.min(365, Math.max(1, Math.floor(cfg.recallTranscriptRetentionDays))) : 30,
1009
+ respectBundledActiveMemoryToggle: cfg.respectBundledActiveMemoryToggle !== false,
1010
+ activeRecallEnabled: cfg.activeRecallEnabled === true,
1011
+ activeRecallAgents: Array.isArray(cfg.activeRecallAgents) && cfg.activeRecallAgents.length > 0 ? cfg.activeRecallAgents.filter((value) => typeof value === "string" && value.trim().length > 0).map((value) => value.trim()) : null,
1012
+ activeRecallAllowedChatTypes: Array.isArray(cfg.activeRecallAllowedChatTypes) && cfg.activeRecallAllowedChatTypes.length > 0 ? cfg.activeRecallAllowedChatTypes.filter(
1013
+ (value) => value === "direct" || value === "group" || value === "channel"
1014
+ ) : ["direct", "group", "channel"],
1015
+ activeRecallQueryMode: cfg.activeRecallQueryMode === "message" || cfg.activeRecallQueryMode === "full" ? cfg.activeRecallQueryMode : "recent",
1016
+ activeRecallPromptStyle: cfg.activeRecallPromptStyle === "strict" || cfg.activeRecallPromptStyle === "contextual" || cfg.activeRecallPromptStyle === "recall-heavy" || cfg.activeRecallPromptStyle === "precision-heavy" || cfg.activeRecallPromptStyle === "preference-only" ? cfg.activeRecallPromptStyle : "balanced",
1017
+ activeRecallCustomInstruction: (() => {
1018
+ const customInstruction = typeof cfg.activeRecallCustomInstruction === "string" ? cfg.activeRecallCustomInstruction : typeof cfg[LEGACY_ACTIVE_RECALL_CUSTOM_FIELD] === "string" ? cfg[LEGACY_ACTIVE_RECALL_CUSTOM_FIELD] : "";
1019
+ return customInstruction.trim().length > 0 ? customInstruction.trim() : null;
1020
+ })(),
1021
+ activeRecallPromptAppend: typeof cfg.activeRecallPromptAppend === "string" && cfg.activeRecallPromptAppend.trim().length > 0 ? cfg.activeRecallPromptAppend.trim() : null,
1022
+ activeRecallMaxSummaryChars: typeof cfg.activeRecallMaxSummaryChars === "number" ? Math.min(1e3, Math.max(40, Math.floor(cfg.activeRecallMaxSummaryChars))) : 220,
1023
+ activeRecallRecentUserTurns: typeof cfg.activeRecallRecentUserTurns === "number" ? Math.min(4, Math.max(0, Math.floor(cfg.activeRecallRecentUserTurns))) : 2,
1024
+ activeRecallRecentAssistantTurns: typeof cfg.activeRecallRecentAssistantTurns === "number" ? Math.min(3, Math.max(0, Math.floor(cfg.activeRecallRecentAssistantTurns))) : 1,
1025
+ activeRecallRecentUserChars: typeof cfg.activeRecallRecentUserChars === "number" ? Math.min(1e3, Math.max(40, Math.floor(cfg.activeRecallRecentUserChars))) : 600,
1026
+ activeRecallRecentAssistantChars: typeof cfg.activeRecallRecentAssistantChars === "number" ? Math.min(1e3, Math.max(40, Math.floor(cfg.activeRecallRecentAssistantChars))) : 400,
1027
+ activeRecallThinking: cfg.activeRecallThinking === "low" || cfg.activeRecallThinking === "off" || cfg.activeRecallThinking === "minimal" || cfg.activeRecallThinking === "medium" || cfg.activeRecallThinking === "high" || cfg.activeRecallThinking === "xhigh" || cfg.activeRecallThinking === "adaptive" ? cfg.activeRecallThinking : "low",
1028
+ activeRecallTimeoutMs: typeof cfg.activeRecallTimeoutMs === "number" ? Math.max(250, Math.floor(cfg.activeRecallTimeoutMs)) : 15e3,
1029
+ activeRecallCacheTtlMs: typeof cfg.activeRecallCacheTtlMs === "number" ? cfg.activeRecallCacheTtlMs === 0 ? 0 : cfg.activeRecallCacheTtlMs < 0 ? 15e3 : Math.min(
1030
+ 12e4,
1031
+ Math.max(1, Math.floor(cfg.activeRecallCacheTtlMs))
1032
+ ) : 15e3,
1033
+ activeRecallModel: typeof cfg.activeRecallModel === "string" && cfg.activeRecallModel.trim().length > 0 ? cfg.activeRecallModel.trim() : null,
1034
+ activeRecallModelFallbackPolicy: cfg.activeRecallModelFallbackPolicy === "resolved-only" ? "resolved-only" : "default-remote",
1035
+ activeRecallPersistTranscripts: cfg.activeRecallPersistTranscripts === true,
1036
+ activeRecallTranscriptDir: typeof cfg.activeRecallTranscriptDir === "string" && cfg.activeRecallTranscriptDir.trim().length > 0 ? cfg.activeRecallTranscriptDir.trim() : "active-recall",
1037
+ activeRecallEntityGraphDepth: typeof cfg.activeRecallEntityGraphDepth === "number" ? Math.min(3, Math.max(0, Math.floor(cfg.activeRecallEntityGraphDepth))) : 1,
1038
+ activeRecallIncludeCausalTrajectories: cfg.activeRecallIncludeCausalTrajectories === true,
1039
+ activeRecallIncludeDaySummary: cfg.activeRecallIncludeDaySummary === true,
1040
+ activeRecallAttachRecallExplain: cfg.activeRecallAttachRecallExplain === true,
1041
+ activeRecallAllowChainedActiveMemory: cfg.activeRecallAllowChainedActiveMemory === true,
1042
+ dreaming,
1043
+ dreamsPhases,
1044
+ procedural,
1045
+ // At-rest encryption (issue #690 PR 3/4)
1046
+ // coerceBool handles CLI string inputs: `--config secureStoreEnabled=true`
1047
+ // arrives as the string "true" which `=== true` would reject (CLAUDE.md #36).
1048
+ secureStoreEnabled: coerceBool(cfg.secureStoreEnabled) === true,
1049
+ secureStoreEncryptOnWrite: coerceBool(cfg.secureStoreEncryptOnWrite) !== false,
1050
+ // default: true
1051
+ codingMode,
1052
+ heartbeat,
1053
+ slotBehavior,
1054
+ codexCompat,
1055
+ // Hourly summaries
1056
+ hourlySummariesEnabled: cfg.hourlySummariesEnabled !== false,
1057
+ // default: true
1058
+ daySummaryEnabled: cfg.daySummaryEnabled !== false,
1059
+ // default: true
1060
+ hourlySummaryCronAutoRegister: cfg.hourlySummaryCronAutoRegister === true,
1061
+ // Codex P1 on PR 763 round 2: gate the nightly-governance cron
1062
+ // (deep-sleep's primary scheduled execution path) on
1063
+ // dreams.phases.deepSleep.enabled. When the phase is disabled the
1064
+ // cron must NOT auto-register, otherwise `deepSleep.enabled=false`
1065
+ // is a contract lie — deep-sleep keeps running.
1066
+ nightlyGovernanceCronAutoRegister: dreamsDeepSleep.enabled && cfg.nightlyGovernanceCronAutoRegister === true,
1067
+ summaryRecallHours: typeof cfg.summaryRecallHours === "number" ? cfg.summaryRecallHours : 24,
1068
+ maxSummaryCount: typeof cfg.maxSummaryCount === "number" ? cfg.maxSummaryCount : 6,
1069
+ summaryModel: typeof cfg.summaryModel === "string" && cfg.summaryModel.length > 0 ? cfg.summaryModel : model,
1070
+ // default: same as extraction model
1071
+ // v2.4 Extended hourly summaries (default off)
1072
+ hourlySummariesExtendedEnabled: cfg.hourlySummariesExtendedEnabled === true,
1073
+ hourlySummariesIncludeToolStats: cfg.hourlySummariesIncludeToolStats === true,
1074
+ hourlySummariesIncludeSystemMessages: cfg.hourlySummariesIncludeSystemMessages === true,
1075
+ hourlySummariesMaxTurnsPerRun: typeof cfg.hourlySummariesMaxTurnsPerRun === "number" ? cfg.hourlySummariesMaxTurnsPerRun : 200,
1076
+ // v2.4 Conversation index (default off)
1077
+ conversationIndexEnabled: cfg.conversationIndexEnabled === true,
1078
+ conversationIndexBackend: cfg.conversationIndexBackend === "faiss" ? "faiss" : "qmd",
1079
+ conversationIndexQmdCollection: typeof cfg.conversationIndexQmdCollection === "string" && cfg.conversationIndexQmdCollection.length > 0 ? cfg.conversationIndexQmdCollection : "openclaw-engram-conversations",
1080
+ conversationIndexRetentionDays: typeof cfg.conversationIndexRetentionDays === "number" ? cfg.conversationIndexRetentionDays : 30,
1081
+ conversationIndexMinUpdateIntervalMs: typeof cfg.conversationIndexMinUpdateIntervalMs === "number" ? cfg.conversationIndexMinUpdateIntervalMs : 15 * 6e4,
1082
+ conversationIndexEmbedOnUpdate: cfg.conversationIndexEmbedOnUpdate === true,
1083
+ conversationIndexFaissScriptPath: typeof cfg.conversationIndexFaissScriptPath === "string" && cfg.conversationIndexFaissScriptPath.trim().length > 0 ? cfg.conversationIndexFaissScriptPath.trim() : void 0,
1084
+ conversationIndexFaissPythonBin: typeof cfg.conversationIndexFaissPythonBin === "string" && cfg.conversationIndexFaissPythonBin.trim().length > 0 ? cfg.conversationIndexFaissPythonBin.trim() : void 0,
1085
+ conversationIndexFaissModelId: typeof cfg.conversationIndexFaissModelId === "string" && cfg.conversationIndexFaissModelId.trim().length > 0 ? cfg.conversationIndexFaissModelId.trim() : "text-embedding-3-small",
1086
+ conversationIndexFaissIndexDir: typeof cfg.conversationIndexFaissIndexDir === "string" && cfg.conversationIndexFaissIndexDir.trim().length > 0 ? cfg.conversationIndexFaissIndexDir.trim() : "state/conversation-index/faiss",
1087
+ conversationIndexFaissUpsertTimeoutMs: typeof cfg.conversationIndexFaissUpsertTimeoutMs === "number" ? Math.max(0, Math.floor(cfg.conversationIndexFaissUpsertTimeoutMs)) : 3e4,
1088
+ conversationIndexFaissSearchTimeoutMs: typeof cfg.conversationIndexFaissSearchTimeoutMs === "number" ? Math.max(0, Math.floor(cfg.conversationIndexFaissSearchTimeoutMs)) : 5e3,
1089
+ conversationIndexFaissHealthTimeoutMs: typeof cfg.conversationIndexFaissHealthTimeoutMs === "number" ? Math.max(0, Math.floor(cfg.conversationIndexFaissHealthTimeoutMs)) : 2e3,
1090
+ conversationIndexFaissMaxBatchSize: typeof cfg.conversationIndexFaissMaxBatchSize === "number" ? Math.max(0, Math.floor(cfg.conversationIndexFaissMaxBatchSize)) : 512,
1091
+ conversationIndexFaissMaxSearchK: typeof cfg.conversationIndexFaissMaxSearchK === "number" ? Math.max(0, Math.floor(cfg.conversationIndexFaissMaxSearchK)) : 50,
1092
+ conversationRecallTopK: typeof cfg.conversationRecallTopK === "number" ? cfg.conversationRecallTopK : 3,
1093
+ conversationRecallMaxChars: typeof cfg.conversationRecallMaxChars === "number" ? cfg.conversationRecallMaxChars : 2500,
1094
+ conversationRecallTimeoutMs: typeof cfg.conversationRecallTimeoutMs === "number" ? cfg.conversationRecallTimeoutMs : 800,
1095
+ evalHarnessEnabled: cfg.evalHarnessEnabled === true,
1096
+ evalShadowModeEnabled: cfg.evalShadowModeEnabled === true,
1097
+ benchmarkBaselineSnapshotsEnabled: cfg.benchmarkBaselineSnapshotsEnabled === true,
1098
+ benchmarkDeltaReporterEnabled: cfg.benchmarkDeltaReporterEnabled === true,
1099
+ benchmarkStoredBaselineEnabled: cfg.benchmarkStoredBaselineEnabled === true,
1100
+ evalStoreDir: typeof cfg.evalStoreDir === "string" && cfg.evalStoreDir.trim().length > 0 ? cfg.evalStoreDir.trim() : path.join(memoryDir, "state", "evals"),
1101
+ objectiveStateMemoryEnabled: cfg.objectiveStateMemoryEnabled === true,
1102
+ objectiveStateSnapshotWritesEnabled: cfg.objectiveStateSnapshotWritesEnabled === true,
1103
+ objectiveStateRecallEnabled: cfg.objectiveStateRecallEnabled === true,
1104
+ objectiveStateStoreDir: typeof cfg.objectiveStateStoreDir === "string" && cfg.objectiveStateStoreDir.trim().length > 0 ? cfg.objectiveStateStoreDir.trim() : path.join(memoryDir, "state", "objective-state"),
1105
+ causalTrajectoryMemoryEnabled: cfg.causalTrajectoryMemoryEnabled === true,
1106
+ causalTrajectoryStoreDir: typeof cfg.causalTrajectoryStoreDir === "string" && cfg.causalTrajectoryStoreDir.trim().length > 0 ? cfg.causalTrajectoryStoreDir.trim() : path.join(memoryDir, "state", "causal-trajectories"),
1107
+ causalTrajectoryRecallEnabled: cfg.causalTrajectoryRecallEnabled === true,
1108
+ actionGraphRecallEnabled: cfg.actionGraphRecallEnabled === true,
1109
+ trustZonesEnabled: cfg.trustZonesEnabled === true,
1110
+ quarantinePromotionEnabled: cfg.quarantinePromotionEnabled === true,
1111
+ trustZoneStoreDir: typeof cfg.trustZoneStoreDir === "string" && cfg.trustZoneStoreDir.trim().length > 0 ? cfg.trustZoneStoreDir.trim() : path.join(memoryDir, "state", "trust-zones"),
1112
+ trustZoneRecallEnabled: cfg.trustZoneRecallEnabled === true,
1113
+ memoryPoisoningDefenseEnabled: cfg.memoryPoisoningDefenseEnabled === true,
1114
+ memoryRedTeamBenchEnabled: cfg.memoryRedTeamBenchEnabled === true,
1115
+ harmonicRetrievalEnabled: cfg.harmonicRetrievalEnabled === true,
1116
+ abstractionAnchorsEnabled: cfg.abstractionAnchorsEnabled === true,
1117
+ verifiedRecallEnabled: cfg.verifiedRecallEnabled === true,
1118
+ semanticRulePromotionEnabled: cfg.semanticRulePromotionEnabled === true,
1119
+ semanticRuleVerificationEnabled: cfg.semanticRuleVerificationEnabled === true,
1120
+ // Issue #678 PR 2/4: when `dreams.phases.rem.*` is set, the resolved
1121
+ // dreamsPhases value WINS over the legacy top-level key. The runtime
1122
+ // gates (orchestrator's `runSemanticConsolidation`) read these legacy
1123
+ // fields, so we must propagate the precedence here, not just in the
1124
+ // `dreamsPhases` object.
1125
+ semanticConsolidationEnabled: dreamsRem.enabled && dreamsRem.cadenceMs > 0,
1126
+ semanticConsolidationModel: typeof cfg.semanticConsolidationModel === "string" && cfg.semanticConsolidationModel.length > 0 ? cfg.semanticConsolidationModel : "auto",
1127
+ semanticConsolidationThreshold: dreamsRem.similarityThreshold,
1128
+ semanticConsolidationMinClusterSize: dreamsRem.minClusterSize,
1129
+ semanticConsolidationExcludeCategories: Array.isArray(cfg.semanticConsolidationExcludeCategories) ? cfg.semanticConsolidationExcludeCategories.filter(
1130
+ (c) => typeof c === "string" && c.length > 0
1131
+ ) : ["correction", "commitment", "procedure"],
1132
+ // semanticConsolidationIntervalHours is derived from dreamsRem.cadenceMs
1133
+ // when an override is set (rounded up to the nearest hour). Preserve
1134
+ // explicit zero so legacy schedulers see the same disable-by-zero signal
1135
+ // as the dreams.phases.rem config; the runtime enabled flag is also
1136
+ // disabled above so zero does not mean "run every maintenance cycle".
1137
+ semanticConsolidationIntervalHours: rawDreamsRem.cadenceMs !== void 0 ? Math.max(0, Math.ceil(dreamsRem.cadenceMs / 36e5)) : legacySemanticConsolidationIntervalHours,
1138
+ semanticConsolidationMaxPerRun: dreamsRem.maxPerRun,
1139
+ // Operator-aware consolidation prompt (issue #561 PR 3). Defaults
1140
+ // to `false` to match sibling `*Enabled` flags' least-privileged
1141
+ // convention. Operators opt in by setting `true` (or truthy
1142
+ // coercions like "true", "1", "yes", "on") when they want the
1143
+ // consolidation LLM to emit SPLIT/MERGE/UPDATE operator selection
1144
+ // on the `derived_via` frontmatter field. Uses `coerceBool` per
1145
+ // Gotcha #36 so CLI / env-string inputs coerce correctly. When
1146
+ // disabled, `derived_via` is still populated via the cluster-shape
1147
+ // heuristic (chooseConsolidationOperator) so PR 2's provenance
1148
+ // wiring keeps working without operator-aware prompts.
1149
+ operatorAwareConsolidationEnabled: coerceBool(cfg.operatorAwareConsolidationEnabled) ?? false,
1150
+ // Pattern reinforcement (issue #687 PR 2/4). Defaults: off, weekly
1151
+ // cadence, min cluster size 3, target categories preference / fact
1152
+ // / decision. All bounds clamped at parse time so invalid inputs
1153
+ // (negative numbers, non-arrays, non-strings) fail safe to defaults
1154
+ // rather than crash the job.
1155
+ patternReinforcementEnabled: coerceBool(cfg.patternReinforcementEnabled) ?? false,
1156
+ patternReinforcementCadenceMs: (() => {
1157
+ const raw2 = coerceNumber(cfg.patternReinforcementCadenceMs);
1158
+ if (raw2 === void 0 || !Number.isFinite(raw2)) {
1159
+ return 7 * 24 * 60 * 60 * 1e3;
1160
+ }
1161
+ return Math.max(0, Math.floor(raw2));
1162
+ })(),
1163
+ patternReinforcementMinCount: (() => {
1164
+ const raw2 = coerceNumber(cfg.patternReinforcementMinCount);
1165
+ if (raw2 === void 0 || !Number.isFinite(raw2)) return 3;
1166
+ return Math.min(1e3, Math.max(2, Math.floor(raw2)));
1167
+ })(),
1168
+ patternReinforcementCategories: Array.isArray(cfg.patternReinforcementCategories) ? cfg.patternReinforcementCategories.filter((v) => typeof v === "string").map((v) => v.trim()).filter((v) => v.length > 0) : ["preference", "fact", "decision"],
1169
+ // issue #687 PR 3/4: reinforcement recall boost config.
1170
+ reinforcementRecallBoostEnabled: coerceBool(cfg.reinforcementRecallBoostEnabled) ?? false,
1171
+ reinforcementRecallBoostWeight: (() => {
1172
+ if (cfg.reinforcementRecallBoostWeight === void 0) return 0.05;
1173
+ const n = coerceNumber(cfg.reinforcementRecallBoostWeight);
1174
+ if (n === void 0 || !Number.isFinite(n) || n < 0 || n > 1) {
1175
+ throw new Error(
1176
+ `reinforcementRecallBoostWeight must be a number in [0, 1] (got ${JSON.stringify(cfg.reinforcementRecallBoostWeight)}).`
1177
+ );
1178
+ }
1179
+ return n;
1180
+ })(),
1181
+ reinforcementRecallBoostMax: (() => {
1182
+ if (cfg.reinforcementRecallBoostMax === void 0) return 0.3;
1183
+ const n = coerceNumber(cfg.reinforcementRecallBoostMax);
1184
+ if (n === void 0 || !Number.isFinite(n) || n < 0 || n > 1) {
1185
+ throw new Error(
1186
+ `reinforcementRecallBoostMax must be a number in [0, 1] (got ${JSON.stringify(cfg.reinforcementRecallBoostMax)}).`
1187
+ );
1188
+ }
1189
+ return n;
1190
+ })(),
1191
+ // Async peer profile reasoner (issue #679 PR 2/5). Defaults to
1192
+ // `false` (opt-in) per Gotchas #30/#48 — least-privileged default.
1193
+ // `coerceBool` handles "true"/"1"/"yes"/"on" CLI strings (Gotcha
1194
+ // #36). Numeric thresholds clamp at zero (Gotcha #28 + #45 — 0
1195
+ // is a documented disable value for both, so the schema minimum
1196
+ // matches and we do NOT silently bump to 1).
1197
+ peerProfileReasonerEnabled: coerceBool(cfg.peerProfileReasonerEnabled) ?? false,
1198
+ // Cursor M on PR #736: use the routing alias `"auto"` rather than
1199
+ // a hardcoded model identifier. Matches the convention established
1200
+ // by sibling `semanticConsolidationModel`. Operators can still
1201
+ // override via config; the value is logged for telemetry only.
1202
+ peerProfileReasonerModel: typeof cfg.peerProfileReasonerModel === "string" && cfg.peerProfileReasonerModel.trim().length > 0 ? cfg.peerProfileReasonerModel.trim() : "auto",
1203
+ // Cursor L on PR #736: numeric config keys must coerce string CLI
1204
+ // values (Gotcha #28 — `--config peerProfileReasonerMaxFieldsPerRun=2`
1205
+ // arrives as the string "2"). Pre-fix `typeof === "number"`
1206
+ // rejected string inputs and silently fell back to defaults. The
1207
+ // shared `coerceNonNegativeInt` helper accepts both forms, throws
1208
+ // on invalid input (Gotcha #51 — reject rather than silently
1209
+ // default), and falls back to the documented default when the
1210
+ // key is absent. 0 is a valid documented disable value here, so
1211
+ // the helper does NOT bump to 1.
1212
+ peerProfileReasonerMinInteractions: coerceNonNegativeInt(
1213
+ cfg.peerProfileReasonerMinInteractions,
1214
+ 5,
1215
+ "peerProfileReasonerMinInteractions"
1216
+ ),
1217
+ peerProfileReasonerMaxFieldsPerRun: coerceNonNegativeInt(
1218
+ cfg.peerProfileReasonerMaxFieldsPerRun,
1219
+ 8,
1220
+ "peerProfileReasonerMaxFieldsPerRun"
1221
+ ),
1222
+ // Peer profile recall injection (issue #679 PR 3/5). Default-off
1223
+ // per Gotcha #30/#48 (least-privileged default, new feature gate).
1224
+ // `coerceBool` handles CLI string forms "true"/"1"/"yes"/"on"
1225
+ // (Gotcha #36). `coerceNonNegativeInt` handles string CLI values
1226
+ // (Gotcha #28) and documents 0 as the disable value (Gotcha #45 —
1227
+ // schema minimum must also be 0 so they stay consistent).
1228
+ peerProfileRecallEnabled: coerceBool(cfg.peerProfileRecallEnabled) ?? false,
1229
+ peerProfileRecallMaxFields: coerceNonNegativeInt(
1230
+ cfg.peerProfileRecallMaxFields,
1231
+ 5,
1232
+ "peerProfileRecallMaxFields"
1233
+ ),
1234
+ creationMemoryEnabled: cfg.creationMemoryEnabled === true,
1235
+ memoryUtilityLearningEnabled: cfg.memoryUtilityLearningEnabled === true,
1236
+ promotionByOutcomeEnabled: cfg.promotionByOutcomeEnabled === true,
1237
+ commitmentLedgerEnabled: cfg.commitmentLedgerEnabled === true,
1238
+ commitmentLifecycleEnabled: cfg.commitmentLifecycleEnabled === true,
1239
+ commitmentStaleDays: typeof cfg.commitmentStaleDays === "number" ? cfg.commitmentStaleDays : 14,
1240
+ commitmentLedgerDir: typeof cfg.commitmentLedgerDir === "string" && cfg.commitmentLedgerDir.trim().length > 0 ? cfg.commitmentLedgerDir.trim() : path.join(memoryDir, "state", "commitment-ledger"),
1241
+ resumeBundlesEnabled: cfg.resumeBundlesEnabled === true,
1242
+ resumeBundleDir: typeof cfg.resumeBundleDir === "string" && cfg.resumeBundleDir.trim().length > 0 ? cfg.resumeBundleDir.trim() : path.join(memoryDir, "state", "resume-bundles"),
1243
+ workProductRecallEnabled: cfg.workProductRecallEnabled === true,
1244
+ workTasksEnabled: cfg.workTasksEnabled === true,
1245
+ workProjectsEnabled: cfg.workProjectsEnabled === true,
1246
+ workTasksDir: typeof cfg.workTasksDir === "string" && cfg.workTasksDir.trim().length > 0 ? cfg.workTasksDir.trim() : path.join(memoryDir, "work", "tasks"),
1247
+ workProjectsDir: typeof cfg.workProjectsDir === "string" && cfg.workProjectsDir.trim().length > 0 ? cfg.workProjectsDir.trim() : path.join(memoryDir, "work", "projects"),
1248
+ workIndexEnabled: cfg.workIndexEnabled === true,
1249
+ workIndexDir: typeof cfg.workIndexDir === "string" && cfg.workIndexDir.trim().length > 0 ? cfg.workIndexDir.trim() : path.join(memoryDir, "work", "index"),
1250
+ workTaskIndexEnabled: cfg.workTaskIndexEnabled === true,
1251
+ workProjectIndexEnabled: cfg.workProjectIndexEnabled === true,
1252
+ workIndexAutoRebuildEnabled: cfg.workIndexAutoRebuildEnabled === true,
1253
+ workIndexAutoRebuildDebounceMs: typeof cfg.workIndexAutoRebuildDebounceMs === "number" ? cfg.workIndexAutoRebuildDebounceMs : 1e3,
1254
+ workProductLedgerDir: typeof cfg.workProductLedgerDir === "string" && cfg.workProductLedgerDir.trim().length > 0 ? cfg.workProductLedgerDir.trim() : path.join(memoryDir, "state", "work-product-ledger"),
1255
+ abstractionNodeStoreDir: typeof cfg.abstractionNodeStoreDir === "string" && cfg.abstractionNodeStoreDir.trim().length > 0 ? cfg.abstractionNodeStoreDir.trim() : path.join(memoryDir, "state", "abstraction-nodes"),
1256
+ // Local LLM Provider (v2.1)
1257
+ localLlmEnabled: cfg.localLlmEnabled === true || cfg.localLlmEnabled === "true",
1258
+ // default: false
1259
+ localLlmUrl: typeof cfg.localLlmUrl === "string" && cfg.localLlmUrl.length > 0 ? cfg.localLlmUrl : "http://localhost:1234/v1",
1260
+ localLlmModel: typeof cfg.localLlmModel === "string" && cfg.localLlmModel.length > 0 ? cfg.localLlmModel : "local-model",
1261
+ localLlmApiKey: typeof cfg.localLlmApiKey === "string" && cfg.localLlmApiKey.length > 0 ? resolveEnvVars(cfg.localLlmApiKey) : void 0,
1262
+ localLlmHeaders: cfg.localLlmHeaders && typeof cfg.localLlmHeaders === "object" && !Array.isArray(cfg.localLlmHeaders) ? Object.fromEntries(
1263
+ Object.entries(cfg.localLlmHeaders).filter(([, value]) => typeof value === "string").map(([key, value]) => [key, String(value)])
1264
+ ) : void 0,
1265
+ localLlmAuthHeader: cfg.localLlmAuthHeader !== false,
1266
+ localLlmFallback: cfg.localLlmFallback !== false,
1267
+ // default: true
1268
+ localLlmHomeDir: typeof cfg.localLlmHomeDir === "string" && cfg.localLlmHomeDir.length > 0 ? cfg.localLlmHomeDir : void 0,
1269
+ localLmsCliPath: typeof cfg.localLmsCliPath === "string" && cfg.localLmsCliPath.length > 0 ? cfg.localLmsCliPath : void 0,
1270
+ localLmsBinDir: typeof cfg.localLmsBinDir === "string" && cfg.localLmsBinDir.length > 0 ? cfg.localLmsBinDir : void 0,
1271
+ localLlmTimeoutMs: parseBoundedIntegerMs(cfg.localLlmTimeoutMs, 18e4, 1, 864e5),
1272
+ localLlmMaxContext: typeof cfg.localLlmMaxContext === "number" ? cfg.localLlmMaxContext : void 0,
1273
+ // Observability (disabled by default to avoid log spam)
1274
+ slowLogEnabled: cfg.slowLogEnabled === true,
1275
+ slowLogThresholdMs: typeof cfg.slowLogThresholdMs === "number" ? cfg.slowLogThresholdMs : 3e4,
1276
+ // Trace recall content — disabled by default; enable to send recalled memory text to trace subscribers
1277
+ traceRecallContent: cfg.traceRecallContent === true,
1278
+ // Performance profiling (opt-in, disabled by default)
1279
+ profilingEnabled: cfg.profilingEnabled === true,
1280
+ profilingStorageDir: typeof cfg.profilingStorageDir === "string" && cfg.profilingStorageDir.length > 0 ? cfg.profilingStorageDir : path.join(memoryDir, "profiling"),
1281
+ profilingMaxTraces: typeof cfg.profilingMaxTraces === "number" && Number.isFinite(cfg.profilingMaxTraces) ? Math.max(0, cfg.profilingMaxTraces) : 100,
1282
+ // Extraction stability guards (P0/P1)
1283
+ extractionDedupeEnabled: cfg.extractionDedupeEnabled !== false,
1284
+ extractionDedupeWindowMs: typeof cfg.extractionDedupeWindowMs === "number" ? cfg.extractionDedupeWindowMs : 5 * 6e4,
1285
+ extractionMinChars: typeof cfg.extractionMinChars === "number" ? cfg.extractionMinChars : 40,
1286
+ extractionMinUserTurns: typeof cfg.extractionMinUserTurns === "number" ? cfg.extractionMinUserTurns : 1,
1287
+ extractionTelemetryPrefilterEnabled: coerceBool(cfg.extractionTelemetryPrefilterEnabled) !== false,
1288
+ extractionMaxTurnChars: typeof cfg.extractionMaxTurnChars === "number" ? cfg.extractionMaxTurnChars : 4e3,
1289
+ extractionMaxFactsPerRun: typeof cfg.extractionMaxFactsPerRun === "number" ? cfg.extractionMaxFactsPerRun : 12,
1290
+ extractionMaxEntitiesPerRun: typeof cfg.extractionMaxEntitiesPerRun === "number" ? cfg.extractionMaxEntitiesPerRun : 6,
1291
+ extractionMaxQuestionsPerRun: typeof cfg.extractionMaxQuestionsPerRun === "number" ? cfg.extractionMaxQuestionsPerRun : 3,
1292
+ extractionMaxProfileUpdatesPerRun: typeof cfg.extractionMaxProfileUpdatesPerRun === "number" ? cfg.extractionMaxProfileUpdatesPerRun : 4,
1293
+ // Importance write-gate for trivial extracted content (issue #372).
1294
+ // Default "low" drops only "trivial" facts (greetings, single-word replies,
1295
+ // heartbeat pings); set to "normal" or higher to make the gate stricter.
1296
+ extractionMinImportanceLevel: (() => {
1297
+ const raw2 = cfg.extractionMinImportanceLevel;
1298
+ if (raw2 === "trivial" || raw2 === "low" || raw2 === "normal" || raw2 === "high" || raw2 === "critical") {
1299
+ return raw2;
1300
+ }
1301
+ return "low";
1302
+ })(),
1303
+ // Extraction scope classification. When enabled, the extraction prompt
1304
+ // asks the LLM to classify each fact as "project" or "global". Global
1305
+ // facts are promoted to the shared namespace. Default true (rule 30 gate).
1306
+ extractionScopeClassificationEnabled: coerceBool(cfg.extractionScopeClassificationEnabled) !== false,
1307
+ // Extraction judge (issue #376). Opt-in LLM-as-judge fact-worthiness gate.
1308
+ extractionJudgeEnabled: cfg.extractionJudgeEnabled === true,
1309
+ extractionJudgeModel: typeof cfg.extractionJudgeModel === "string" ? cfg.extractionJudgeModel : "",
1310
+ extractionJudgeBatchSize: typeof cfg.extractionJudgeBatchSize === "number" && Number.isFinite(cfg.extractionJudgeBatchSize) ? Math.max(1, Math.round(cfg.extractionJudgeBatchSize)) : 20,
1311
+ extractionJudgeShadow: cfg.extractionJudgeShadow === true,
1312
+ // Defer cap (issue #562 PR 2): max re-deferrals for the same candidate
1313
+ // text before the verdict is forcibly converted to reject.
1314
+ extractionJudgeMaxDeferrals: typeof cfg.extractionJudgeMaxDeferrals === "number" && Number.isFinite(cfg.extractionJudgeMaxDeferrals) && cfg.extractionJudgeMaxDeferrals >= 1 ? Math.floor(cfg.extractionJudgeMaxDeferrals) : 2,
1315
+ // Judge telemetry (issue #562 PR 3): opt-in structured emit to the
1316
+ // observation ledger for defer-rate / latency metrics.
1317
+ // Uses `coerceBool` so CLI-style string inputs (`"true"`, `"false"`,
1318
+ // `"1"`, `"0"`) are accepted consistently with the rest of the
1319
+ // codebase (CLAUDE.md gotcha 36).
1320
+ extractionJudgeTelemetryEnabled: coerceBool(cfg.extractionJudgeTelemetryEnabled) === true,
1321
+ // Judge training-pair collection (issue #562 PR 4): opt-in shim for a
1322
+ // future GRPO training pipeline. Rows land under ~/.remnic/judge-
1323
+ // training/<date>.jsonl — NOT in the shared memory directory.
1324
+ // Uses `coerceBool` per CLAUDE.md gotcha 36 for CLI-string parity.
1325
+ collectJudgeTrainingPairs: coerceBool(cfg.collectJudgeTrainingPairs) === true,
1326
+ judgeTrainingDir: typeof cfg.judgeTrainingDir === "string" ? cfg.judgeTrainingDir : "",
1327
+ // Inline source attribution (issue #369). Opt-in to preserve
1328
+ // backwards compatibility with existing downstream consumers.
1329
+ inlineSourceAttributionEnabled: cfg.inlineSourceAttributionEnabled === true,
1330
+ inlineSourceAttributionFormat: typeof cfg.inlineSourceAttributionFormat === "string" && cfg.inlineSourceAttributionFormat.trim().length > 0 ? cfg.inlineSourceAttributionFormat : "[Source: agent={agent}, session={sessionId}, ts={ts}]",
1331
+ consolidationRequireNonZeroExtraction: cfg.consolidationRequireNonZeroExtraction !== false,
1332
+ // Issue #678 PR 2/4: dreams.phases.rem.minIntervalMs WINS when set.
1333
+ consolidationMinIntervalMs: dreamsRem.minIntervalMs,
1334
+ // QMD maintenance (debounced singleflight)
1335
+ qmdMaintenanceEnabled: cfg.qmdMaintenanceEnabled !== false,
1336
+ qmdMaintenanceDebounceMs: typeof cfg.qmdMaintenanceDebounceMs === "number" ? cfg.qmdMaintenanceDebounceMs : 3e4,
1337
+ qmdAutoEmbedEnabled: cfg.qmdAutoEmbedEnabled === true,
1338
+ qmdEmbedMinIntervalMs: typeof cfg.qmdEmbedMinIntervalMs === "number" ? cfg.qmdEmbedMinIntervalMs : 60 * 6e4,
1339
+ qmdUpdateTimeoutMs: typeof cfg.qmdUpdateTimeoutMs === "number" ? cfg.qmdUpdateTimeoutMs : 9e4,
1340
+ qmdUpdateMinIntervalMs: typeof cfg.qmdUpdateMinIntervalMs === "number" ? cfg.qmdUpdateMinIntervalMs : 15 * 6e4,
1341
+ // Local LLM resilience
1342
+ localLlmRetry5xxCount: typeof cfg.localLlmRetry5xxCount === "number" ? cfg.localLlmRetry5xxCount : 1,
1343
+ localLlmRetryBackoffMs: typeof cfg.localLlmRetryBackoffMs === "number" ? cfg.localLlmRetryBackoffMs : 400,
1344
+ localLlm400TripThreshold: typeof cfg.localLlm400TripThreshold === "number" ? cfg.localLlm400TripThreshold : 5,
1345
+ localLlm400CooldownMs: typeof cfg.localLlm400CooldownMs === "number" ? cfg.localLlm400CooldownMs : 12e4,
1346
+ // Local LLM fast tier (v9.1)
1347
+ localLlmFastEnabled: cfg.localLlmFastEnabled === true,
1348
+ localLlmFastModel: typeof cfg.localLlmFastModel === "string" && cfg.localLlmFastModel.length > 0 ? cfg.localLlmFastModel : "",
1349
+ localLlmFastUrl: typeof cfg.localLlmFastUrl === "string" && cfg.localLlmFastUrl.length > 0 ? cfg.localLlmFastUrl : typeof cfg.localLlmUrl === "string" && cfg.localLlmUrl.length > 0 ? cfg.localLlmUrl : "http://localhost:1234/v1",
1350
+ localLlmFastTimeoutMs: typeof cfg.localLlmFastTimeoutMs === "number" ? cfg.localLlmFastTimeoutMs : 15e3,
1351
+ // Thinking-mode suppression on the main local LLM (issue #548).
1352
+ // Default true — extraction / consolidation produce structured
1353
+ // JSON and gain nothing from chain-of-thought; thinking-capable
1354
+ // models burn their token budget on reasoning and blow the
1355
+ // default 60s timeout. Operators who need thinking on the main
1356
+ // client (e.g. for narrative tasks) can set this to false via
1357
+ // config or --config CLI flag. The fast-tier `fastLlm` always
1358
+ // disables thinking and is unaffected by this flag.
1359
+ //
1360
+ // Injection is backend-gated inside LocalLlmClient: the
1361
+ // `chat_template_kwargs` field is only sent when the detected
1362
+ // backend is in `THINKING_COMPATIBLE_BACKENDS` (LM Studio, vLLM).
1363
+ // Strict OpenAI-compatible backends reject unknown request
1364
+ // fields with 400, so the client fails open on unknown backends
1365
+ // rather than tripping the 400 cooldown (Codex P1 on PR #550).
1366
+ localLlmDisableThinking: coerceBool(cfg.localLlmDisableThinking) ?? true,
1367
+ // Gateway config (passed from index.ts for fallback AI)
1368
+ gatewayConfig: cfg.gatewayConfig,
1369
+ // Gateway model source (v9.2) — route LLM calls through gateway agent model chain
1370
+ modelSource,
1371
+ gatewayAgentId: typeof cfg.gatewayAgentId === "string" && cfg.gatewayAgentId.length > 0 ? cfg.gatewayAgentId : "",
1372
+ fastGatewayAgentId: typeof cfg.fastGatewayAgentId === "string" && cfg.fastGatewayAgentId.length > 0 ? cfg.fastGatewayAgentId : "",
1373
+ // v3.0 namespaces (default off)
1374
+ namespacesEnabled: cfg.namespacesEnabled === true,
1375
+ defaultNamespace: typeof cfg.defaultNamespace === "string" && cfg.defaultNamespace.length > 0 ? cfg.defaultNamespace : "default",
1376
+ sharedNamespace: typeof cfg.sharedNamespace === "string" && cfg.sharedNamespace.length > 0 ? cfg.sharedNamespace : "shared",
1377
+ principalFromSessionKeyMode: cfg.principalFromSessionKeyMode === "prefix" ? "prefix" : cfg.principalFromSessionKeyMode === "regex" ? "regex" : "map",
1378
+ principalFromSessionKeyRules: principalRules,
1379
+ namespacePolicies: Array.isArray(cfg.namespacePolicies) ? cfg.namespacePolicies.map((p) => ({
1380
+ name: typeof p?.name === "string" ? p.name : "",
1381
+ readPrincipals: Array.isArray(p?.readPrincipals) ? p.readPrincipals.filter((x) => typeof x === "string") : [],
1382
+ writePrincipals: Array.isArray(p?.writePrincipals) ? p.writePrincipals.filter((x) => typeof x === "string") : [],
1383
+ includeInRecallByDefault: p?.includeInRecallByDefault === true
1384
+ })).filter((p) => p.name.length > 0) : [],
1385
+ defaultRecallNamespaces: Array.isArray(cfg.defaultRecallNamespaces) ? ["self", "shared"].filter((x) => cfg.defaultRecallNamespaces.includes(x)) : ["self", "shared"],
1386
+ cronRecallMode: cfg.cronRecallMode === "none" ? "none" : cfg.cronRecallMode === "allowlist" ? "allowlist" : "all",
1387
+ cronRecallAllowlist: Array.isArray(cfg.cronRecallAllowlist) ? cfg.cronRecallAllowlist.filter((v) => typeof v === "string" && v.length > 0) : [],
1388
+ cronRecallPolicyEnabled: cfg.cronRecallPolicyEnabled !== false,
1389
+ cronRecallNormalizedQueryMaxChars: typeof cfg.cronRecallNormalizedQueryMaxChars === "number" ? cfg.cronRecallNormalizedQueryMaxChars : 480,
1390
+ cronRecallInstructionHeavyTokenCap: typeof cfg.cronRecallInstructionHeavyTokenCap === "number" ? cfg.cronRecallInstructionHeavyTokenCap : 36,
1391
+ cronConversationRecallMode: cfg.cronConversationRecallMode === "always" ? "always" : cfg.cronConversationRecallMode === "never" ? "never" : "auto",
1392
+ autoPromoteToSharedEnabled: cfg.autoPromoteToSharedEnabled === true,
1393
+ autoPromoteToSharedCategories: Array.isArray(cfg.autoPromoteToSharedCategories) ? cfg.autoPromoteToSharedCategories.filter((c) => c === "fact" || c === "correction" || c === "decision" || c === "preference") : ["fact", "correction", "decision", "preference"],
1394
+ autoPromoteMinConfidenceTier: cfg.autoPromoteMinConfidenceTier === "explicit" ? "explicit" : cfg.autoPromoteMinConfidenceTier === "implied" ? "implied" : "explicit",
1395
+ routingRulesEnabled: cfg.routingRulesEnabled === true,
1396
+ routingRulesStateFile: typeof cfg.routingRulesStateFile === "string" && cfg.routingRulesStateFile.trim().length > 0 ? cfg.routingRulesStateFile.trim() : "state/routing-rules.json",
1397
+ // v4.0 shared-context (default off)
1398
+ sharedContextEnabled: cfg.sharedContextEnabled === true,
1399
+ sharedContextDir: typeof cfg.sharedContextDir === "string" && cfg.sharedContextDir.length > 0 ? cfg.sharedContextDir : void 0,
1400
+ sharedContextMaxInjectChars: typeof cfg.sharedContextMaxInjectChars === "number" ? cfg.sharedContextMaxInjectChars : 4e3,
1401
+ sharedCrossSignalSemanticEnabled,
1402
+ sharedCrossSignalSemanticTimeoutMs,
1403
+ sharedCrossSignalSemanticMaxCandidates: typeof cfg.sharedCrossSignalSemanticMaxCandidates === "number" ? Math.max(0, Math.floor(cfg.sharedCrossSignalSemanticMaxCandidates)) : 120,
1404
+ // Backward-compatible aliases.
1405
+ crossSignalsSemanticEnabled: sharedCrossSignalSemanticEnabled,
1406
+ crossSignalsSemanticTimeoutMs: sharedCrossSignalSemanticTimeoutMs,
1407
+ // v5.0 compounding (default off)
1408
+ compoundingEnabled: cfg.compoundingEnabled === true,
1409
+ compoundingWeeklyCronEnabled: cfg.compoundingWeeklyCronEnabled === true,
1410
+ compoundingSemanticEnabled: cfg.compoundingSemanticEnabled === true,
1411
+ compoundingSynthesisTimeoutMs: typeof cfg.compoundingSynthesisTimeoutMs === "number" ? cfg.compoundingSynthesisTimeoutMs : 15e3,
1412
+ compoundingInjectEnabled: cfg.compoundingInjectEnabled !== false,
1413
+ // IRC (Inductive Rule Consolidation) — preference synthesis
1414
+ ircEnabled: cfg.ircEnabled !== false,
1415
+ ircMaxPreferences: typeof cfg.ircMaxPreferences === "number" ? cfg.ircMaxPreferences : 20,
1416
+ ircIncludeCorrections: cfg.ircIncludeCorrections !== false,
1417
+ ircMinConfidence: typeof cfg.ircMinConfidence === "number" ? cfg.ircMinConfidence : 0.3,
1418
+ // CMC (Causal Memory Consolidation) — cross-session causal reasoning
1419
+ cmcEnabled: cfg.cmcEnabled === true,
1420
+ cmcStitchLookbackDays: typeof cfg.cmcStitchLookbackDays === "number" ? cfg.cmcStitchLookbackDays : 7,
1421
+ cmcStitchMinScore: typeof cfg.cmcStitchMinScore === "number" ? cfg.cmcStitchMinScore : 2.5,
1422
+ cmcStitchMaxEdgesPerTrajectory: typeof cfg.cmcStitchMaxEdgesPerTrajectory === "number" ? cfg.cmcStitchMaxEdgesPerTrajectory : 3,
1423
+ cmcConsolidationEnabled: cfg.cmcConsolidationEnabled === true,
1424
+ cmcConsolidationMinRecurrence: typeof cfg.cmcConsolidationMinRecurrence === "number" ? cfg.cmcConsolidationMinRecurrence : 3,
1425
+ cmcConsolidationMinSessions: typeof cfg.cmcConsolidationMinSessions === "number" ? cfg.cmcConsolidationMinSessions : 2,
1426
+ cmcConsolidationSuccessThreshold: typeof cfg.cmcConsolidationSuccessThreshold === "number" ? cfg.cmcConsolidationSuccessThreshold : 0.7,
1427
+ cmcRetrievalEnabled: cfg.cmcRetrievalEnabled === true,
1428
+ cmcRetrievalMaxDepth: typeof cfg.cmcRetrievalMaxDepth === "number" ? cfg.cmcRetrievalMaxDepth : 3,
1429
+ cmcRetrievalMaxChars: typeof cfg.cmcRetrievalMaxChars === "number" ? cfg.cmcRetrievalMaxChars : 800,
1430
+ cmcRetrievalCounterfactualBoost: typeof cfg.cmcRetrievalCounterfactualBoost === "number" ? cfg.cmcRetrievalCounterfactualBoost : 0.4,
1431
+ cmcBehaviorLearningEnabled: cfg.cmcBehaviorLearningEnabled === true,
1432
+ cmcBehaviorMinFrequency: typeof cfg.cmcBehaviorMinFrequency === "number" ? cfg.cmcBehaviorMinFrequency : 3,
1433
+ cmcBehaviorMinSessions: typeof cfg.cmcBehaviorMinSessions === "number" ? cfg.cmcBehaviorMinSessions : 2,
1434
+ cmcBehaviorConfidenceThreshold: typeof cfg.cmcBehaviorConfidenceThreshold === "number" ? cfg.cmcBehaviorConfidenceThreshold : 0.6,
1435
+ cmcLifecycleCausalImpactWeight: typeof cfg.cmcLifecycleCausalImpactWeight === "number" ? cfg.cmcLifecycleCausalImpactWeight : 0.05,
1436
+ // PEDC (Prediction-Error-Driven Calibration) — model-user alignment
1437
+ calibrationEnabled: cfg.calibrationEnabled === true,
1438
+ calibrationMaxRulesPerRecall: typeof cfg.calibrationMaxRulesPerRecall === "number" ? cfg.calibrationMaxRulesPerRecall : 10,
1439
+ calibrationMaxChars: typeof cfg.calibrationMaxChars === "number" ? cfg.calibrationMaxChars : 1200,
1440
+ // v7.0 Knowledge Graph Enhancement
1441
+ knowledgeIndexEnabled: cfg.knowledgeIndexEnabled !== false,
1442
+ knowledgeIndexMaxEntities: typeof cfg.knowledgeIndexMaxEntities === "number" ? cfg.knowledgeIndexMaxEntities : 40,
1443
+ knowledgeIndexMaxChars: typeof cfg.knowledgeIndexMaxChars === "number" ? cfg.knowledgeIndexMaxChars : 4e3,
1444
+ entityRetrievalEnabled: cfg.entityRetrievalEnabled !== false,
1445
+ entityRetrievalMaxChars: typeof cfg.entityRetrievalMaxChars === "number" ? cfg.entityRetrievalMaxChars : 2400,
1446
+ entityRetrievalMaxHints: typeof cfg.entityRetrievalMaxHints === "number" ? cfg.entityRetrievalMaxHints : 2,
1447
+ entityRetrievalMaxSupportingFacts: typeof cfg.entityRetrievalMaxSupportingFacts === "number" ? cfg.entityRetrievalMaxSupportingFacts : 6,
1448
+ entityRetrievalMaxRelatedEntities: typeof cfg.entityRetrievalMaxRelatedEntities === "number" ? cfg.entityRetrievalMaxRelatedEntities : 3,
1449
+ entityRetrievalRecentTurns: typeof cfg.entityRetrievalRecentTurns === "number" ? cfg.entityRetrievalRecentTurns : 6,
1450
+ entitySchemas,
1451
+ recallBudgetChars: recallPipelineConfig.recallBudgetChars,
1452
+ recallOuterTimeoutMs: typeof cfg.recallOuterTimeoutMs === "number" ? Math.max(0, Math.floor(cfg.recallOuterTimeoutMs)) : 75e3,
1453
+ recallCoreDeadlineMs: typeof cfg.recallCoreDeadlineMs === "number" ? Math.max(0, Math.floor(cfg.recallCoreDeadlineMs)) : 75e3,
1454
+ recallEnrichmentDeadlineMs: typeof cfg.recallEnrichmentDeadlineMs === "number" ? Math.max(0, Math.floor(cfg.recallEnrichmentDeadlineMs)) : 25e3,
1455
+ recallPipeline: recallPipelineConfig.pipeline,
1456
+ recallMmrEnabled: cfg.recallMmrEnabled !== false,
1457
+ recallMmrLambda: typeof cfg.recallMmrLambda === "number" && Number.isFinite(cfg.recallMmrLambda) ? Math.min(1, Math.max(0, cfg.recallMmrLambda)) : 0.7,
1458
+ recallMmrTopN: typeof cfg.recallMmrTopN === "number" && Number.isFinite(cfg.recallMmrTopN) ? Math.max(0, Math.floor(cfg.recallMmrTopN)) : 40,
1459
+ // Issue #564 PR 3: off by default; enable explicitly after bench validation.
1460
+ recallReasoningTraceBoostEnabled: coerceBool(cfg.recallReasoningTraceBoostEnabled) ?? false,
1461
+ qmdRecallCacheTtlMs: typeof cfg.qmdRecallCacheTtlMs === "number" ? Math.max(0, Math.floor(cfg.qmdRecallCacheTtlMs)) : 6e4,
1462
+ qmdRecallCacheStaleTtlMs: typeof cfg.qmdRecallCacheStaleTtlMs === "number" ? Math.max(0, Math.floor(cfg.qmdRecallCacheStaleTtlMs)) : 10 * 6e4,
1463
+ qmdRecallCacheMaxEntries: typeof cfg.qmdRecallCacheMaxEntries === "number" ? Math.max(0, Math.floor(cfg.qmdRecallCacheMaxEntries)) : 128,
1464
+ entityRelationshipsEnabled: cfg.entityRelationshipsEnabled !== false,
1465
+ entityActivityLogEnabled: cfg.entityActivityLogEnabled !== false,
1466
+ entityActivityLogMaxEntries: typeof cfg.entityActivityLogMaxEntries === "number" ? cfg.entityActivityLogMaxEntries : 20,
1467
+ entityAliasesEnabled: cfg.entityAliasesEnabled !== false,
1468
+ entitySummaryEnabled: cfg.entitySummaryEnabled !== false,
1469
+ entitySynthesisMaxTokens: typeof cfg.entitySynthesisMaxTokens === "number" && Number.isFinite(cfg.entitySynthesisMaxTokens) ? (() => {
1470
+ const tokens = Math.max(0, Math.floor(cfg.entitySynthesisMaxTokens));
1471
+ return tokens === 0 ? 0 : Math.max(10, tokens);
1472
+ })() : 500,
1473
+ // Search backend abstraction
1474
+ searchBackend: ["qmd", "remote", "noop", "lancedb", "meilisearch", "orama"].includes(cfg.searchBackend) ? cfg.searchBackend : "qmd",
1475
+ remoteSearchBaseUrl: typeof cfg.remoteSearchBaseUrl === "string" ? cfg.remoteSearchBaseUrl : void 0,
1476
+ remoteSearchApiKey: typeof cfg.remoteSearchApiKey === "string" ? cfg.remoteSearchApiKey : void 0,
1477
+ remoteSearchTimeoutMs: typeof cfg.remoteSearchTimeoutMs === "number" ? cfg.remoteSearchTimeoutMs : 3e4,
1478
+ // LanceDB backend
1479
+ lancedbEnabled: cfg.lancedbEnabled === true,
1480
+ lanceDbPath: typeof cfg.lanceDbPath === "string" ? cfg.lanceDbPath : path.join(memoryDir, "lancedb"),
1481
+ lanceEmbeddingDimension: typeof cfg.lanceEmbeddingDimension === "number" ? cfg.lanceEmbeddingDimension : 1536,
1482
+ // Meilisearch backend
1483
+ meilisearchEnabled: cfg.meilisearchEnabled === true,
1484
+ meilisearchHost: typeof cfg.meilisearchHost === "string" ? cfg.meilisearchHost : "http://localhost:7700",
1485
+ meilisearchApiKey: typeof cfg.meilisearchApiKey === "string" ? cfg.meilisearchApiKey : void 0,
1486
+ meilisearchTimeoutMs: typeof cfg.meilisearchTimeoutMs === "number" ? cfg.meilisearchTimeoutMs : 3e4,
1487
+ meilisearchAutoIndex: cfg.meilisearchAutoIndex === true,
1488
+ // Orama backend
1489
+ oramaEnabled: cfg.oramaEnabled === true,
1490
+ oramaDbPath: typeof cfg.oramaDbPath === "string" ? cfg.oramaDbPath : path.join(memoryDir, "orama"),
1491
+ oramaEmbeddingDimension: typeof cfg.oramaEmbeddingDimension === "number" ? cfg.oramaEmbeddingDimension : 1536,
1492
+ // QMD daemon mode
1493
+ qmdDaemonEnabled: cfg.qmdDaemonEnabled !== false,
1494
+ qmdDaemonUrl: typeof cfg.qmdDaemonUrl === "string" && cfg.qmdDaemonUrl.length > 0 ? cfg.qmdDaemonUrl : "http://localhost:8181/mcp",
1495
+ qmdDaemonRecheckIntervalMs: typeof cfg.qmdDaemonRecheckIntervalMs === "number" ? cfg.qmdDaemonRecheckIntervalMs : 15e3,
1496
+ qmdIntentHintsEnabled: cfg.qmdIntentHintsEnabled === true,
1497
+ qmdExplainEnabled: cfg.qmdExplainEnabled === true,
1498
+ // v6.0 Fact deduplication & archival
1499
+ factDeduplicationEnabled: cfg.factDeduplicationEnabled !== false,
1500
+ // Issue #373 — write-time semantic similarity guard
1501
+ semanticDedupEnabled: cfg.semanticDedupEnabled !== false,
1502
+ // Guard against NaN / Infinity — Number.isFinite rejects both and falls
1503
+ // back to the documented default so the semantic dedup guard cannot be
1504
+ // silently disabled by a malformed config value.
1505
+ semanticDedupThreshold: typeof cfg.semanticDedupThreshold === "number" && Number.isFinite(cfg.semanticDedupThreshold) ? Math.min(1, Math.max(0, cfg.semanticDedupThreshold)) : 0.92,
1506
+ // Zero is a valid "disable candidate lookup" signal and must be preserved.
1507
+ // Only negative or non-finite values fall back to the default of 5.
1508
+ // Fractional values in (0, 1) floor to 0, which would silently disable
1509
+ // semantic dedup despite a clearly non-zero operator intent — clamp to 1.
1510
+ semanticDedupCandidates: (() => {
1511
+ const raw2 = cfg.semanticDedupCandidates;
1512
+ if (typeof raw2 !== "number" || !Number.isFinite(raw2) || raw2 < 0) return 5;
1513
+ const n = Math.floor(raw2);
1514
+ return raw2 > 0 && n === 0 ? 1 : n;
1515
+ })(),
1516
+ factArchivalEnabled: cfg.factArchivalEnabled === true,
1517
+ factArchivalAgeDays: typeof cfg.factArchivalAgeDays === "number" ? cfg.factArchivalAgeDays : 90,
1518
+ factArchivalMaxImportance: typeof cfg.factArchivalMaxImportance === "number" ? cfg.factArchivalMaxImportance : 0.3,
1519
+ factArchivalMaxAccessCount: typeof cfg.factArchivalMaxAccessCount === "number" ? cfg.factArchivalMaxAccessCount : 2,
1520
+ factArchivalProtectedCategories: Array.isArray(cfg.factArchivalProtectedCategories) ? cfg.factArchivalProtectedCategories.filter((c) => typeof c === "string") : ["commitment", "preference", "decision", "principle", "procedure"],
1521
+ // Lifecycle policy engine (issue #686 PR 3/6 — flipped default to
1522
+ // `true`). Tier infrastructure (`tier-routing.ts`,
1523
+ // `tier-migration.ts`, separate cold QMD collection) has shipped
1524
+ // for several releases. Default-on lets the year-2 retention
1525
+ // story land for every install instead of staying gated behind
1526
+ // an opt-in flag the typical operator never reaches. Operators
1527
+ // who need pre-#686 behavior (no automatic hot↔cold migration,
1528
+ // no recall-time stale filtering) can set
1529
+ // `lifecyclePolicyEnabled: false` explicitly. Coerce string/number
1530
+ // boolean-likes (e.g. CLI `--config lifecyclePolicyEnabled=false`)
1531
+ // before applying the default — otherwise an explicit false-ish
1532
+ // input falls through and silently re-enables the policy.
1533
+ // Issue #678 PR 2/4: dreams.phases.lightSleep.* WINS over legacy keys.
1534
+ // The runtime gate (orchestrator's `runLifecyclePolicyPass`) reads
1535
+ // these legacy fields, so propagate the precedence here.
1536
+ lifecyclePolicyEnabled: dreamsLightSleep.enabled,
1537
+ lifecycleFilterStaleEnabled: dreamsLightSleep.filterStaleEnabled,
1538
+ lifecyclePromoteHeatThreshold: dreamsLightSleep.promoteHeatThreshold,
1539
+ lifecycleStaleDecayThreshold: dreamsLightSleep.staleDecayThreshold,
1540
+ lifecycleArchiveDecayThreshold: dreamsLightSleep.archiveDecayThreshold,
1541
+ lifecycleProtectedCategories: Array.isArray(cfg.lifecycleProtectedCategories) ? cfg.lifecycleProtectedCategories.filter(
1542
+ (c) => typeof c === "string" && VALID_MEMORY_CATEGORIES.has(c)
1543
+ ) : ["decision", "principle", "commitment", "preference", "procedure"],
1544
+ // Mirror the *resolved* lifecyclePolicyEnabled default (not the
1545
+ // raw input) — otherwise omitting both flags returns `false` for
1546
+ // metrics even though the policy is enabled by default since
1547
+ // #686 PR 3/6.
1548
+ // Issue #678 PR 2/4: mirror the resolved dreams light-sleep enabled flag
1549
+ // (which already incorporates dreams.phases precedence + legacy fallback).
1550
+ lifecycleMetricsEnabled: coerceBooleanLike(cfg.lifecycleMetricsEnabled) ?? dreamsLightSleep.enabled,
1551
+ // v8.3 proactive + policy learning (default off)
1552
+ proactiveExtractionEnabled: cfg.proactiveExtractionEnabled === true,
1553
+ contextCompressionActionsEnabled: cfg.contextCompressionActionsEnabled === true,
1554
+ compressionGuidelineLearningEnabled: cfg.compressionGuidelineLearningEnabled === true,
1555
+ compressionGuidelineSemanticRefinementEnabled: cfg.compressionGuidelineSemanticRefinementEnabled === true,
1556
+ compressionGuidelineSemanticTimeoutMs: typeof cfg.compressionGuidelineSemanticTimeoutMs === "number" ? Math.max(1, Math.floor(cfg.compressionGuidelineSemanticTimeoutMs)) : 2500,
1557
+ maxProactiveQuestionsPerExtraction: typeof cfg.maxProactiveQuestionsPerExtraction === "number" ? Math.max(0, Math.floor(cfg.maxProactiveQuestionsPerExtraction)) : 2,
1558
+ proactiveExtractionTimeoutMs: typeof cfg.proactiveExtractionTimeoutMs === "number" ? Math.max(0, Math.floor(cfg.proactiveExtractionTimeoutMs)) : 2500,
1559
+ proactiveExtractionMaxTokens: typeof cfg.proactiveExtractionMaxTokens === "number" ? Math.max(0, Math.floor(cfg.proactiveExtractionMaxTokens)) : 900,
1560
+ extractionMaxOutputTokens: typeof cfg.extractionMaxOutputTokens === "number" ? Math.max(1, Math.floor(cfg.extractionMaxOutputTokens)) : 16384,
1561
+ proactiveExtractionCategoryAllowlist: Array.isArray(cfg.proactiveExtractionCategoryAllowlist) ? cfg.proactiveExtractionCategoryAllowlist.filter(
1562
+ (category) => typeof category === "string" && VALID_MEMORY_CATEGORIES.has(category)
1563
+ ) : void 0,
1564
+ maxCompressionTokensPerHour: typeof cfg.maxCompressionTokensPerHour === "number" ? Math.max(0, Math.floor(cfg.maxCompressionTokensPerHour)) : 1500,
1565
+ behaviorLoopAutoTuneEnabled: cfg.behaviorLoopAutoTuneEnabled === true,
1566
+ behaviorLoopLearningWindowDays: typeof cfg.behaviorLoopLearningWindowDays === "number" ? Math.max(0, Math.floor(cfg.behaviorLoopLearningWindowDays)) : 14,
1567
+ behaviorLoopMinSignalCount: typeof cfg.behaviorLoopMinSignalCount === "number" ? Math.max(0, Math.floor(cfg.behaviorLoopMinSignalCount)) : 10,
1568
+ behaviorLoopMaxDeltaPerCycle: typeof cfg.behaviorLoopMaxDeltaPerCycle === "number" ? Math.min(1, Math.max(0, cfg.behaviorLoopMaxDeltaPerCycle)) : 0.1,
1569
+ behaviorLoopProtectedParams: Array.isArray(cfg.behaviorLoopProtectedParams) ? cfg.behaviorLoopProtectedParams.filter((param) => typeof param === "string" && param.trim().length > 0) : [...DEFAULT_BEHAVIOR_LOOP_PROTECTED_PARAMS],
1570
+ // v8.0 phase 1
1571
+ recallPlannerEnabled: cfg.recallPlannerEnabled !== false,
1572
+ recallPlannerModel: typeof cfg.recallPlannerModel === "string" && cfg.recallPlannerModel.trim().length > 0 ? cfg.recallPlannerModel.trim() : DEFAULT_REASONING_MODEL,
1573
+ recallPlannerTimeoutMs: typeof cfg.recallPlannerTimeoutMs === "number" ? cfg.recallPlannerTimeoutMs : 1500,
1574
+ recallPlannerUseResponsesApi: cfg.recallPlannerUseResponsesApi !== false,
1575
+ recallPlannerMaxPromptChars: typeof cfg.recallPlannerMaxPromptChars === "number" ? cfg.recallPlannerMaxPromptChars : 4e3,
1576
+ recallPlannerMaxMemoryHints: typeof cfg.recallPlannerMaxMemoryHints === "number" ? cfg.recallPlannerMaxMemoryHints : 24,
1577
+ recallPlannerShadowMode: cfg.recallPlannerShadowMode === true,
1578
+ recallPlannerTelemetryEnabled: cfg.recallPlannerTelemetryEnabled !== false,
1579
+ recallPlannerMaxQmdResultsMinimal: typeof cfg.recallPlannerMaxQmdResultsMinimal === "number" ? cfg.recallPlannerMaxQmdResultsMinimal : 4,
1580
+ recallPlannerMaxQmdResultsFull: typeof cfg.recallPlannerMaxQmdResultsFull === "number" ? cfg.recallPlannerMaxQmdResultsFull : 8,
1581
+ intentRoutingEnabled: cfg.intentRoutingEnabled === true,
1582
+ intentRoutingBoost: typeof cfg.intentRoutingBoost === "number" ? cfg.intentRoutingBoost : 0.12,
1583
+ verbatimArtifactsEnabled: cfg.verbatimArtifactsEnabled === true,
1584
+ verbatimArtifactsMinConfidence: typeof cfg.verbatimArtifactsMinConfidence === "number" ? cfg.verbatimArtifactsMinConfidence : 0.8,
1585
+ verbatimArtifactsMaxRecall: typeof cfg.verbatimArtifactsMaxRecall === "number" ? cfg.verbatimArtifactsMaxRecall : 5,
1586
+ verbatimArtifactCategories: Array.isArray(cfg.verbatimArtifactCategories) ? cfg.verbatimArtifactCategories.filter(
1587
+ (c) => typeof c === "string" && VALID_MEMORY_CATEGORIES.has(c)
1588
+ ) : ["decision", "correction", "principle", "commitment"],
1589
+ // v8.0 Phase 2A: Memory Boxes + Trace Weaving
1590
+ memoryBoxesEnabled: cfg.memoryBoxesEnabled === true,
1591
+ boxTopicShiftThreshold: typeof cfg.boxTopicShiftThreshold === "number" ? cfg.boxTopicShiftThreshold : 0.35,
1592
+ boxTimeGapMs: typeof cfg.boxTimeGapMs === "number" ? cfg.boxTimeGapMs : 30 * 60 * 1e3,
1593
+ boxMaxMemories: typeof cfg.boxMaxMemories === "number" ? cfg.boxMaxMemories : 50,
1594
+ traceWeaverEnabled: cfg.traceWeaverEnabled === true,
1595
+ traceWeaverLookbackDays: typeof cfg.traceWeaverLookbackDays === "number" ? cfg.traceWeaverLookbackDays : 7,
1596
+ traceWeaverOverlapThreshold: typeof cfg.traceWeaverOverlapThreshold === "number" ? cfg.traceWeaverOverlapThreshold : 0.4,
1597
+ boxRecallDays: typeof cfg.boxRecallDays === "number" ? cfg.boxRecallDays : 3,
1598
+ // v8.0 Phase 2B: Episode/Note dual store (HiMem)
1599
+ episodeNoteModeEnabled: cfg.episodeNoteModeEnabled === true,
1600
+ // v8.1: Temporal + Tag Indexes (SwiftMem-inspired)
1601
+ queryAwareIndexingEnabled: cfg.queryAwareIndexingEnabled === true,
1602
+ queryAwareIndexingMaxCandidates: typeof cfg.queryAwareIndexingMaxCandidates === "number" ? Math.max(0, cfg.queryAwareIndexingMaxCandidates) : 200,
1603
+ temporalIndexWindowDays: typeof cfg.temporalIndexWindowDays === "number" ? cfg.temporalIndexWindowDays : 30,
1604
+ temporalIndexMaxEntries: typeof cfg.temporalIndexMaxEntries === "number" ? cfg.temporalIndexMaxEntries : 5e3,
1605
+ temporalBoostRecentDays: typeof cfg.temporalBoostRecentDays === "number" ? cfg.temporalBoostRecentDays : 7,
1606
+ temporalBoostScore: typeof cfg.temporalBoostScore === "number" ? cfg.temporalBoostScore : 0.15,
1607
+ temporalDecayEnabled: cfg.temporalDecayEnabled !== false,
1608
+ tagMemoryEnabled: cfg.tagMemoryEnabled === true,
1609
+ tagMaxPerMemory: typeof cfg.tagMaxPerMemory === "number" ? cfg.tagMaxPerMemory : 5,
1610
+ tagIndexMaxEntries: typeof cfg.tagIndexMaxEntries === "number" ? cfg.tagIndexMaxEntries : 1e4,
1611
+ tagRecallBoost: typeof cfg.tagRecallBoost === "number" ? cfg.tagRecallBoost : 0.15,
1612
+ tagRecallMaxMatches: typeof cfg.tagRecallMaxMatches === "number" ? cfg.tagRecallMaxMatches : 10,
1613
+ // v8.2: Multi-graph memory (PR 18)
1614
+ multiGraphMemoryEnabled: cfg.multiGraphMemoryEnabled === true,
1615
+ graphRecallEnabled: cfg.graphRecallEnabled === true,
1616
+ graphRecallMaxExpansions: typeof cfg.graphRecallMaxExpansions === "number" ? cfg.graphRecallMaxExpansions : 3,
1617
+ graphRecallMaxPerSeed: typeof cfg.graphRecallMaxPerSeed === "number" ? cfg.graphRecallMaxPerSeed : 5,
1618
+ graphRecallMinEdgeWeight: typeof cfg.graphRecallMinEdgeWeight === "number" ? cfg.graphRecallMinEdgeWeight : 0.1,
1619
+ graphRecallShadowEnabled: cfg.graphRecallShadowEnabled === true,
1620
+ graphRecallSnapshotEnabled: cfg.graphRecallSnapshotEnabled === true,
1621
+ graphRecallShadowSampleRate: typeof cfg.graphRecallShadowSampleRate === "number" ? cfg.graphRecallShadowSampleRate : 0.1,
1622
+ graphRecallExplainToolEnabled: cfg.graphRecallExplainToolEnabled === true,
1623
+ graphRecallStoreColdMirror: cfg.graphRecallStoreColdMirror === true,
1624
+ graphRecallColdMirrorCollection: typeof cfg.graphRecallColdMirrorCollection === "string" && cfg.graphRecallColdMirrorCollection.trim().length > 0 ? cfg.graphRecallColdMirrorCollection.trim() : void 0,
1625
+ graphRecallColdMirrorMinAgeDays: typeof cfg.graphRecallColdMirrorMinAgeDays === "number" ? cfg.graphRecallColdMirrorMinAgeDays : 7,
1626
+ graphRecallUseEntityPriors: cfg.graphRecallUseEntityPriors === true,
1627
+ graphRecallEntityPriorBoost: typeof cfg.graphRecallEntityPriorBoost === "number" ? cfg.graphRecallEntityPriorBoost : 0.2,
1628
+ graphRecallPreferHubSeeds: cfg.graphRecallPreferHubSeeds === true,
1629
+ graphRecallHubBias: typeof cfg.graphRecallHubBias === "number" ? cfg.graphRecallHubBias : 0.3,
1630
+ graphRecallRecencyHalfLifeDays: typeof cfg.graphRecallRecencyHalfLifeDays === "number" ? cfg.graphRecallRecencyHalfLifeDays : 30,
1631
+ graphRecallDampingFactor: typeof cfg.graphRecallDampingFactor === "number" ? cfg.graphRecallDampingFactor : 0.85,
1632
+ graphRecallMaxSeedNodes: typeof cfg.graphRecallMaxSeedNodes === "number" ? cfg.graphRecallMaxSeedNodes : 10,
1633
+ graphRecallMaxExpandedNodes: typeof cfg.graphRecallMaxExpandedNodes === "number" ? cfg.graphRecallMaxExpandedNodes : 30,
1634
+ graphRecallMaxTrailPerNode: typeof cfg.graphRecallMaxTrailPerNode === "number" ? cfg.graphRecallMaxTrailPerNode : 5,
1635
+ graphRecallMinSeedScore: typeof cfg.graphRecallMinSeedScore === "number" ? cfg.graphRecallMinSeedScore : 0.3,
1636
+ graphRecallExpansionScoreThreshold: typeof cfg.graphRecallExpansionScoreThreshold === "number" ? cfg.graphRecallExpansionScoreThreshold : 0.2,
1637
+ graphRecallExplainMaxPaths: typeof cfg.graphRecallExplainMaxPaths === "number" ? cfg.graphRecallExplainMaxPaths : 3,
1638
+ graphRecallExplainMaxChars: typeof cfg.graphRecallExplainMaxChars === "number" ? cfg.graphRecallExplainMaxChars : 500,
1639
+ graphRecallExplainEdgeLimit: typeof cfg.graphRecallExplainEdgeLimit === "number" ? cfg.graphRecallExplainEdgeLimit : 5,
1640
+ graphRecallExplainEnabled: cfg.graphRecallExplainEnabled === true,
1641
+ graphRecallEntityHintsEnabled: cfg.graphRecallEntityHintsEnabled === true,
1642
+ graphRecallEntityHintMax: typeof cfg.graphRecallEntityHintMax === "number" ? cfg.graphRecallEntityHintMax : 3,
1643
+ graphRecallEntityHintMaxChars: typeof cfg.graphRecallEntityHintMaxChars === "number" ? cfg.graphRecallEntityHintMaxChars : 200,
1644
+ graphRecallSnapshotDir: typeof cfg.graphRecallSnapshotDir === "string" && cfg.graphRecallSnapshotDir.trim().length > 0 ? cfg.graphRecallSnapshotDir.trim() : path.join(memoryDir, "state", "graph"),
1645
+ graphRecallEnableTrace: cfg.graphRecallEnableTrace === true,
1646
+ graphRecallEnableDebug: cfg.graphRecallEnableDebug === true,
1647
+ graphExpandedIntentEnabled: cfg.graphExpandedIntentEnabled !== false,
1648
+ graphAssistInFullModeEnabled: cfg.graphAssistInFullModeEnabled !== false,
1649
+ graphAssistShadowEvalEnabled: cfg.graphAssistShadowEvalEnabled === true,
1650
+ graphAssistMinSeedResults: typeof cfg.graphAssistMinSeedResults === "number" ? Math.max(1, Math.floor(cfg.graphAssistMinSeedResults)) : 3,
1651
+ entityGraphEnabled: cfg.entityGraphEnabled !== false,
1652
+ timeGraphEnabled: cfg.timeGraphEnabled !== false,
1653
+ graphWriteSessionAdjacencyEnabled: cfg.graphWriteSessionAdjacencyEnabled !== false,
1654
+ causalGraphEnabled: cfg.causalGraphEnabled !== false,
1655
+ maxGraphTraversalSteps: typeof cfg.maxGraphTraversalSteps === "number" ? Math.max(0, cfg.maxGraphTraversalSteps) : 3,
1656
+ graphActivationDecay: typeof cfg.graphActivationDecay === "number" ? Math.min(1, Math.max(0, cfg.graphActivationDecay)) : 0.7,
1657
+ graphExpansionActivationWeight: typeof cfg.graphExpansionActivationWeight === "number" ? Math.min(1, Math.max(0, cfg.graphExpansionActivationWeight)) : 0.65,
1658
+ graphExpansionBlendMin: typeof cfg.graphExpansionBlendMin === "number" ? Math.min(1, Math.max(0, cfg.graphExpansionBlendMin)) : 0.05,
1659
+ graphExpansionBlendMax: typeof cfg.graphExpansionBlendMax === "number" ? Math.min(1, Math.max(0, cfg.graphExpansionBlendMax)) : 0.95,
1660
+ maxEntityGraphEdgesPerMemory: typeof cfg.maxEntityGraphEdgesPerMemory === "number" ? Math.max(0, cfg.maxEntityGraphEdgesPerMemory) : 10,
1661
+ delinearizeEnabled: cfg.delinearizeEnabled !== false,
1662
+ recallConfidenceGateEnabled: cfg.recallConfidenceGateEnabled === true,
1663
+ recallConfidenceGateThreshold: typeof cfg.recallConfidenceGateThreshold === "number" ? Math.max(0, Math.min(1, cfg.recallConfidenceGateThreshold)) : 0.12,
1664
+ causalRuleExtractionEnabled: cfg.causalRuleExtractionEnabled === true,
1665
+ memoryReconstructionEnabled: cfg.memoryReconstructionEnabled === true,
1666
+ memoryReconstructionMaxExpansions: typeof cfg.memoryReconstructionMaxExpansions === "number" ? Math.max(0, Math.round(cfg.memoryReconstructionMaxExpansions)) : 3,
1667
+ graphLateralInhibitionEnabled: cfg.graphLateralInhibitionEnabled !== false,
1668
+ graphLateralInhibitionBeta: typeof cfg.graphLateralInhibitionBeta === "number" ? Math.max(0, Math.min(1, cfg.graphLateralInhibitionBeta)) : 0.15,
1669
+ graphLateralInhibitionTopM: typeof cfg.graphLateralInhibitionTopM === "number" ? Math.max(0, Math.round(cfg.graphLateralInhibitionTopM)) : 7,
1670
+ // Issue #681 PR 2/3 — graph-edge confidence decay maintenance.
1671
+ // Boolean coerced via shared helper (gotcha #36: string "false" is truthy).
1672
+ graphEdgeDecayEnabled: coerceBooleanLike(cfg.graphEdgeDecayEnabled) ?? false,
1673
+ graphEdgeDecayCadenceMs: typeof cfg.graphEdgeDecayCadenceMs === "number" && Number.isFinite(cfg.graphEdgeDecayCadenceMs) ? Math.max(6e4, Math.floor(cfg.graphEdgeDecayCadenceMs)) : 7 * 24 * 60 * 60 * 1e3,
1674
+ graphEdgeDecayWindowMs: typeof cfg.graphEdgeDecayWindowMs === "number" && Number.isFinite(cfg.graphEdgeDecayWindowMs) ? Math.max(6e4, Math.floor(cfg.graphEdgeDecayWindowMs)) : 90 * 24 * 60 * 60 * 1e3,
1675
+ graphEdgeDecayPerWindow: typeof cfg.graphEdgeDecayPerWindow === "number" && Number.isFinite(cfg.graphEdgeDecayPerWindow) ? Math.max(0, Math.min(1, cfg.graphEdgeDecayPerWindow)) : 0.1,
1676
+ graphEdgeDecayFloor: typeof cfg.graphEdgeDecayFloor === "number" && Number.isFinite(cfg.graphEdgeDecayFloor) ? Math.max(0, Math.min(1, cfg.graphEdgeDecayFloor)) : 0.1,
1677
+ graphEdgeDecayVisibilityThreshold: typeof cfg.graphEdgeDecayVisibilityThreshold === "number" && Number.isFinite(cfg.graphEdgeDecayVisibilityThreshold) ? Math.max(0, Math.min(1, cfg.graphEdgeDecayVisibilityThreshold)) : 0.2,
1678
+ // Issue #681 PR 3/3 — confidence-aware traversal & PageRank refinement.
1679
+ // Floor clamps to [0, 1] so misconfigured input cannot accept negative
1680
+ // confidences or reject every edge. Iterations floors at 0 so a
1681
+ // documented 0 disables PageRank refinement and BFS scores pass through.
1682
+ graphTraversalConfidenceFloor: typeof cfg.graphTraversalConfidenceFloor === "number" && Number.isFinite(cfg.graphTraversalConfidenceFloor) ? Math.min(1, Math.max(0, cfg.graphTraversalConfidenceFloor)) : 0.2,
1683
+ graphTraversalPageRankIterations: typeof cfg.graphTraversalPageRankIterations === "number" && Number.isFinite(cfg.graphTraversalPageRankIterations) && cfg.graphTraversalPageRankIterations >= 0 ? Math.floor(cfg.graphTraversalPageRankIterations) : 8,
1684
+ // v8.2: Temporal Memory Tree
1685
+ temporalMemoryTreeEnabled: cfg.temporalMemoryTreeEnabled === true,
1686
+ tmtHourlyMinMemories: typeof cfg.tmtHourlyMinMemories === "number" ? cfg.tmtHourlyMinMemories : 3,
1687
+ tmtSummaryMaxTokens: typeof cfg.tmtSummaryMaxTokens === "number" ? cfg.tmtSummaryMaxTokens : 300,
1688
+ explicitCueRecallEnabled: coerceBool(cfg.explicitCueRecallEnabled) === true,
1689
+ explicitCueRecallMaxChars: coerceNumber(cfg.explicitCueRecallMaxChars) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxChars))) : 2400,
1690
+ explicitCueRecallMaxReferences: coerceNumber(cfg.explicitCueRecallMaxReferences) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxReferences))) : 24,
1691
+ targetedFactRecallEnabled: coerceBool(cfg.targetedFactRecallEnabled) === true,
1692
+ targetedFactRecallMaxChars: parseIntegerAtLeast(cfg.targetedFactRecallMaxChars, 2400, 0, "targetedFactRecallMaxChars"),
1693
+ targetedFactRecallMaxResults: parseIntegerAtLeast(cfg.targetedFactRecallMaxResults, 48, 0, "targetedFactRecallMaxResults"),
1694
+ targetedFactRecallScanWindowTurns: parseIntegerAtLeast(cfg.targetedFactRecallScanWindowTurns, 8, 1, "targetedFactRecallScanWindowTurns"),
1695
+ targetedFactRecallScanWindowTokens: parseIntegerAtLeast(cfg.targetedFactRecallScanWindowTokens, 12e3, 1, "targetedFactRecallScanWindowTokens"),
1696
+ focusedListRecallEnabled: coerceBool(cfg.focusedListRecallEnabled) === true,
1697
+ focusedListRecallMaxChars: parseIntegerAtLeast(cfg.focusedListRecallMaxChars, 2600, 0, "focusedListRecallMaxChars"),
1698
+ focusedListRecallMaxResults: parseIntegerAtLeast(cfg.focusedListRecallMaxResults, 40, 0, "focusedListRecallMaxResults"),
1699
+ focusedListRecallScanWindowTurns: parseIntegerAtLeast(cfg.focusedListRecallScanWindowTurns, 64, 1, "focusedListRecallScanWindowTurns"),
1700
+ focusedListRecallScanWindowTokens: parseIntegerAtLeast(cfg.focusedListRecallScanWindowTokens, 14e3, 1, "focusedListRecallScanWindowTokens"),
1701
+ responseGuidanceRecallEnabled: coerceBool(cfg.responseGuidanceRecallEnabled) === true,
1702
+ responseGuidanceRecallMaxChars: parseIntegerAtLeast(cfg.responseGuidanceRecallMaxChars, 2400, 0, "responseGuidanceRecallMaxChars"),
1703
+ responseGuidanceRecallMaxResults: parseIntegerAtLeast(cfg.responseGuidanceRecallMaxResults, 48, 0, "responseGuidanceRecallMaxResults"),
1704
+ responseGuidanceRecallScanWindowTurns: parseIntegerAtLeast(cfg.responseGuidanceRecallScanWindowTurns, 64, 1, "responseGuidanceRecallScanWindowTurns"),
1705
+ responseGuidanceRecallScanWindowTokens: parseIntegerAtLeast(cfg.responseGuidanceRecallScanWindowTokens, 16e3, 1, "responseGuidanceRecallScanWindowTokens"),
1706
+ eventOrderRecallEnabled: coerceBool(cfg.eventOrderRecallEnabled) === true,
1707
+ eventOrderRecallMaxChars: parseIntegerAtLeast(cfg.eventOrderRecallMaxChars, 2400, 0, "eventOrderRecallMaxChars"),
1708
+ eventOrderRecallMaxResults: parseIntegerAtLeast(cfg.eventOrderRecallMaxResults, 24, 0, "eventOrderRecallMaxResults"),
1709
+ eventOrderRecallScanWindowTurns: parseIntegerAtLeast(cfg.eventOrderRecallScanWindowTurns, 12, 1, "eventOrderRecallScanWindowTurns"),
1710
+ eventOrderRecallScanWindowTokens: parseIntegerAtLeast(cfg.eventOrderRecallScanWindowTokens, 24e3, 1, "eventOrderRecallScanWindowTokens"),
1711
+ // Lossless Context Management (LCM)
1712
+ lcmEnabled: cfg.lcmEnabled === true,
1713
+ lcmLeafBatchSize: typeof cfg.lcmLeafBatchSize === "number" ? Math.max(2, Math.floor(cfg.lcmLeafBatchSize)) : 8,
1714
+ lcmRollupFanIn: typeof cfg.lcmRollupFanIn === "number" ? Math.max(2, Math.floor(cfg.lcmRollupFanIn)) : 4,
1715
+ lcmFreshTailTurns: typeof cfg.lcmFreshTailTurns === "number" ? Math.max(1, Math.floor(cfg.lcmFreshTailTurns)) : 16,
1716
+ lcmMaxDepth: typeof cfg.lcmMaxDepth === "number" ? Math.max(1, Math.floor(cfg.lcmMaxDepth)) : 5,
1717
+ lcmRecallBudgetShare: typeof cfg.lcmRecallBudgetShare === "number" ? Math.max(0, Math.min(1, cfg.lcmRecallBudgetShare)) : 0.15,
1718
+ lcmDeterministicMaxTokens: typeof cfg.lcmDeterministicMaxTokens === "number" ? Math.max(64, Math.floor(cfg.lcmDeterministicMaxTokens)) : 512,
1719
+ lcmTelemetryPrefilterEnabled: coerceBool(cfg.lcmTelemetryPrefilterEnabled) !== false,
1720
+ lcmArchiveRetentionDays: typeof cfg.lcmArchiveRetentionDays === "number" ? Math.max(1, Math.floor(cfg.lcmArchiveRetentionDays)) : 90,
1721
+ lcmObserveConcurrency: parseIntegerAtLeast(cfg.lcmObserveConcurrency, 1, 1, "lcmObserveConcurrency"),
1722
+ messagePartsEnabled: coerceBooleanLike(cfg.messagePartsEnabled) === true,
1723
+ messagePartsRecallMaxResults: typeof cfg.messagePartsRecallMaxResults === "number" ? Math.max(0, Math.floor(cfg.messagePartsRecallMaxResults)) : 6,
1724
+ // v9.1 Parallel Specialized Retrieval
1725
+ parallelRetrievalEnabled: cfg.parallelRetrievalEnabled === true,
1726
+ parallelAgentWeights: (() => {
1727
+ const w = cfg.parallelAgentWeights;
1728
+ return {
1729
+ direct: typeof w?.direct === "number" ? Math.max(0, w.direct) : 1,
1730
+ contextual: typeof w?.contextual === "number" ? Math.max(0, w.contextual) : 0.7,
1731
+ temporal: typeof w?.temporal === "number" ? Math.max(0, w.temporal) : 0.85
1732
+ };
1733
+ })(),
1734
+ parallelMaxResultsPerAgent: typeof cfg.parallelMaxResultsPerAgent === "number" ? Math.max(0, Math.floor(cfg.parallelMaxResultsPerAgent)) : 20,
1735
+ briefing: parseBriefingConfig(cfg.briefing),
1736
+ // Codex CLI connector settings (install-time)
1737
+ codex: (() => {
1738
+ const raw2 = cfg.codex && typeof cfg.codex === "object" && !Array.isArray(cfg.codex) ? cfg.codex : {};
1739
+ const installExtension = coerceInstallExtension(raw2.installExtension) ?? true;
1740
+ const codexHome = typeof raw2.codexHome === "string" && raw2.codexHome.trim().length > 0 ? raw2.codexHome.trim() : null;
1741
+ return { installExtension, codexHome };
1742
+ })(),
1743
+ // Live connectors (issue #683 PR 2/N).
1744
+ //
1745
+ // Per CLAUDE.md gotcha #30 and #48, every concrete connector ships
1746
+ // disabled-by-default and the parser MUST reject malformed top-level
1747
+ // shapes loudly (gotcha #51) rather than silently producing an empty
1748
+ // object.
1749
+ //
1750
+ // We do NOT validate credential strings here — the connector module
1751
+ // re-validates on every sync pass via `validateGoogleDriveConfig`.
1752
+ // That keeps secret-store-driven values (which may legitimately be
1753
+ // empty until the operator runs setup) round-trippable through the
1754
+ // config layer without crashing the orchestrator at boot.
1755
+ connectors: (() => {
1756
+ if (cfg.connectors !== void 0 && (cfg.connectors === null || typeof cfg.connectors !== "object" || Array.isArray(cfg.connectors))) {
1757
+ throw new Error(
1758
+ `connectors must be an object (got ${JSON.stringify(cfg.connectors)}). Use connectors: {} to opt out of every live connector.`
1759
+ );
1760
+ }
1761
+ const rawConnectors = cfg.connectors && typeof cfg.connectors === "object" && !Array.isArray(cfg.connectors) ? cfg.connectors : {};
1762
+ if (rawConnectors.googleDrive !== void 0 && (rawConnectors.googleDrive === null || typeof rawConnectors.googleDrive !== "object" || Array.isArray(rawConnectors.googleDrive))) {
1763
+ throw new Error(
1764
+ `connectors.googleDrive must be an object (got ${JSON.stringify(rawConnectors.googleDrive)}).`
1765
+ );
1766
+ }
1767
+ const rawDrive = rawConnectors.googleDrive && typeof rawConnectors.googleDrive === "object" && !Array.isArray(rawConnectors.googleDrive) ? rawConnectors.googleDrive : {};
1768
+ const driveEnabled = coerceBool(rawDrive.enabled) === true;
1769
+ const driveClientId = typeof rawDrive.clientId === "string" ? rawDrive.clientId : "";
1770
+ const driveClientSecret = typeof rawDrive[CLIENT_SECRET_FIELD] === "string" ? rawDrive[CLIENT_SECRET_FIELD] : "";
1771
+ const driveRefreshToken = typeof rawDrive[REFRESH_TOKEN_FIELD] === "string" ? rawDrive[REFRESH_TOKEN_FIELD] : "";
1772
+ const drivePollCoerced = coerceNumber(rawDrive.pollIntervalMs);
1773
+ let drivePollIntervalMs = 3e5;
1774
+ if (drivePollCoerced !== void 0) {
1775
+ if (!Number.isFinite(drivePollCoerced) || !Number.isInteger(drivePollCoerced) || drivePollCoerced < 1e3 || drivePollCoerced > 864e5) {
1776
+ throw new Error(
1777
+ `connectors.googleDrive.pollIntervalMs must be an integer in [1000, 86400000] ms (got ${JSON.stringify(rawDrive.pollIntervalMs)})`
1778
+ );
1779
+ }
1780
+ drivePollIntervalMs = drivePollCoerced;
1781
+ }
1782
+ let driveFolderIds = [];
1783
+ if (rawDrive.folderIds !== void 0) {
1784
+ if (!Array.isArray(rawDrive.folderIds)) {
1785
+ throw new Error(
1786
+ `connectors.googleDrive.folderIds must be an array of strings (got ${typeof rawDrive.folderIds})`
1787
+ );
1788
+ }
1789
+ const seen = /* @__PURE__ */ new Set();
1790
+ for (const value of rawDrive.folderIds) {
1791
+ if (typeof value !== "string") {
1792
+ throw new Error(
1793
+ `connectors.googleDrive.folderIds entries must be strings; found ${typeof value}`
1794
+ );
1795
+ }
1796
+ const trimmed = value.trim();
1797
+ if (trimmed.length === 0) continue;
1798
+ if (seen.has(trimmed)) continue;
1799
+ seen.add(trimmed);
1800
+ driveFolderIds.push(trimmed);
1801
+ }
1802
+ }
1803
+ if (rawConnectors.notion !== void 0 && (rawConnectors.notion === null || typeof rawConnectors.notion !== "object" || Array.isArray(rawConnectors.notion))) {
1804
+ throw new Error(
1805
+ `connectors.notion must be an object (got ${JSON.stringify(rawConnectors.notion)}).`
1806
+ );
1807
+ }
1808
+ const rawNotion = rawConnectors.notion && typeof rawConnectors.notion === "object" && !Array.isArray(rawConnectors.notion) ? rawConnectors.notion : {};
1809
+ const notionEnabled = coerceBool(rawNotion.enabled) === true;
1810
+ const notionToken = typeof rawNotion.token === "string" ? rawNotion.token : "";
1811
+ const notionPollCoerced = coerceNumber(rawNotion.pollIntervalMs);
1812
+ let notionPollIntervalMs = 3e5;
1813
+ if (notionPollCoerced !== void 0) {
1814
+ if (!Number.isFinite(notionPollCoerced) || !Number.isInteger(notionPollCoerced) || notionPollCoerced < 1e3 || notionPollCoerced > 864e5) {
1815
+ throw new Error(
1816
+ `connectors.notion.pollIntervalMs must be an integer in [1000, 86400000] ms (got ${JSON.stringify(rawNotion.pollIntervalMs)})`
1817
+ );
1818
+ }
1819
+ notionPollIntervalMs = notionPollCoerced;
1820
+ }
1821
+ let notionDatabaseIds = [];
1822
+ if (rawNotion.databaseIds !== void 0) {
1823
+ if (!Array.isArray(rawNotion.databaseIds)) {
1824
+ throw new Error(
1825
+ `connectors.notion.databaseIds must be an array of strings (got ${typeof rawNotion.databaseIds})`
1826
+ );
1827
+ }
1828
+ const seen = /* @__PURE__ */ new Set();
1829
+ for (const value of rawNotion.databaseIds) {
1830
+ if (typeof value !== "string") {
1831
+ throw new Error(
1832
+ `connectors.notion.databaseIds entries must be strings; found ${typeof value}`
1833
+ );
1834
+ }
1835
+ const trimmed = value.trim();
1836
+ if (trimmed.length === 0) continue;
1837
+ if (seen.has(trimmed)) continue;
1838
+ seen.add(trimmed);
1839
+ notionDatabaseIds.push(trimmed);
1840
+ }
1841
+ }
1842
+ if (rawConnectors.gmail !== void 0 && (rawConnectors.gmail === null || typeof rawConnectors.gmail !== "object" || Array.isArray(rawConnectors.gmail))) {
1843
+ throw new Error(
1844
+ `connectors.gmail must be an object (got ${JSON.stringify(rawConnectors.gmail)}).`
1845
+ );
1846
+ }
1847
+ const rawGmail = rawConnectors.gmail && typeof rawConnectors.gmail === "object" && !Array.isArray(rawConnectors.gmail) ? rawConnectors.gmail : {};
1848
+ const gmailEnabled = coerceBool(rawGmail.enabled) === true;
1849
+ const gmailClientId = typeof rawGmail.clientId === "string" ? rawGmail.clientId : "";
1850
+ const gmailClientSecret = typeof rawGmail[CLIENT_SECRET_FIELD] === "string" ? rawGmail[CLIENT_SECRET_FIELD] : "";
1851
+ const gmailRefreshToken = typeof rawGmail[REFRESH_TOKEN_FIELD] === "string" ? rawGmail[REFRESH_TOKEN_FIELD] : "";
1852
+ const gmailUserId = typeof rawGmail.userId === "string" && rawGmail.userId.trim().length > 0 ? rawGmail.userId.trim() : "me";
1853
+ const gmailQuery = typeof rawGmail.query === "string" ? rawGmail.query : "in:inbox";
1854
+ const gmailPollCoerced = coerceNumber(rawGmail.pollIntervalMs);
1855
+ let gmailPollIntervalMs = 3e5;
1856
+ if (rawGmail.pollIntervalMs !== void 0) {
1857
+ if (gmailPollCoerced === void 0) {
1858
+ throw new Error(
1859
+ `connectors.gmail.pollIntervalMs must be a finite number; got ${JSON.stringify(rawGmail.pollIntervalMs)}`
1860
+ );
1861
+ }
1862
+ if (gmailPollCoerced <= 0) {
1863
+ throw new Error(
1864
+ `connectors.gmail.pollIntervalMs must be positive; got ${JSON.stringify(rawGmail.pollIntervalMs)}`
1865
+ );
1866
+ }
1867
+ if (!Number.isInteger(gmailPollCoerced) || gmailPollCoerced < 1e3 || gmailPollCoerced > 864e5) {
1868
+ throw new Error(
1869
+ `connectors.gmail.pollIntervalMs must be an integer in [1000, 86400000] ms (got ${JSON.stringify(rawGmail.pollIntervalMs)})`
1870
+ );
1871
+ }
1872
+ gmailPollIntervalMs = gmailPollCoerced;
1873
+ }
1874
+ if (rawConnectors.github !== void 0 && (rawConnectors.github === null || typeof rawConnectors.github !== "object" || Array.isArray(rawConnectors.github))) {
1875
+ throw new Error(
1876
+ `connectors.github must be an object (got ${JSON.stringify(rawConnectors.github)}).`
1877
+ );
1878
+ }
1879
+ const rawGitHub = rawConnectors.github && typeof rawConnectors.github === "object" && !Array.isArray(rawConnectors.github) ? rawConnectors.github : {};
1880
+ const githubEnabled = coerceBool(rawGitHub.enabled) === true;
1881
+ const githubToken = typeof rawGitHub.token === "string" ? rawGitHub.token : "";
1882
+ const githubUserLogin = typeof rawGitHub.userLogin === "string" ? rawGitHub.userLogin : "";
1883
+ const githubPollCoerced = coerceNumber(rawGitHub.pollIntervalMs);
1884
+ let githubPollIntervalMs = 3e5;
1885
+ if (githubPollCoerced !== void 0) {
1886
+ if (!Number.isFinite(githubPollCoerced) || !Number.isInteger(githubPollCoerced) || githubPollCoerced < 1e3 || githubPollCoerced > 864e5) {
1887
+ throw new Error(
1888
+ `connectors.github.pollIntervalMs must be an integer in [1000, 86400000] ms (got ${JSON.stringify(rawGitHub.pollIntervalMs)})`
1889
+ );
1890
+ }
1891
+ githubPollIntervalMs = githubPollCoerced;
1892
+ }
1893
+ let githubRepos = [];
1894
+ if (rawGitHub.repos !== void 0) {
1895
+ if (!Array.isArray(rawGitHub.repos)) {
1896
+ throw new Error(
1897
+ `connectors.github.repos must be an array of strings (got ${typeof rawGitHub.repos})`
1898
+ );
1899
+ }
1900
+ const seen = /* @__PURE__ */ new Set();
1901
+ for (const value of rawGitHub.repos) {
1902
+ if (typeof value !== "string") {
1903
+ throw new Error(
1904
+ `connectors.github.repos entries must be strings; found ${typeof value}`
1905
+ );
1906
+ }
1907
+ const trimmed = value.trim();
1908
+ if (trimmed.length === 0) continue;
1909
+ if (seen.has(trimmed)) continue;
1910
+ seen.add(trimmed);
1911
+ githubRepos.push(trimmed);
1912
+ }
1913
+ }
1914
+ const githubIncludeDiscussions = coerceBool(rawGitHub.includeDiscussions) === true;
1915
+ return {
1916
+ googleDrive: {
1917
+ enabled: driveEnabled,
1918
+ clientId: driveClientId,
1919
+ [CLIENT_SECRET_FIELD]: driveClientSecret,
1920
+ [REFRESH_TOKEN_FIELD]: driveRefreshToken,
1921
+ pollIntervalMs: drivePollIntervalMs,
1922
+ folderIds: driveFolderIds
1923
+ },
1924
+ notion: {
1925
+ enabled: notionEnabled,
1926
+ token: notionToken,
1927
+ databaseIds: notionDatabaseIds,
1928
+ pollIntervalMs: notionPollIntervalMs
1929
+ },
1930
+ gmail: {
1931
+ enabled: gmailEnabled,
1932
+ clientId: gmailClientId,
1933
+ [CLIENT_SECRET_FIELD]: gmailClientSecret,
1934
+ [REFRESH_TOKEN_FIELD]: gmailRefreshToken,
1935
+ userId: gmailUserId,
1936
+ query: gmailQuery,
1937
+ pollIntervalMs: gmailPollIntervalMs
1938
+ },
1939
+ github: {
1940
+ enabled: githubEnabled,
1941
+ token: githubToken,
1942
+ userLogin: githubUserLogin,
1943
+ repos: githubRepos,
1944
+ pollIntervalMs: githubPollIntervalMs,
1945
+ includeDiscussions: githubIncludeDiscussions
1946
+ }
1947
+ };
1948
+ })(),
1949
+ // MECE Taxonomy (#366)
1950
+ // Coerce string booleans from CLI (e.g. --config taxonomyEnabled=true) — gotcha #36
1951
+ taxonomyEnabled: coerceBool(cfg.taxonomyEnabled) ?? false,
1952
+ taxonomyAutoGenResolver: coerceBool(cfg.taxonomyAutoGenResolver) ?? true,
1953
+ // Codex CLI — native memory materialization (#378)
1954
+ codexMaterializeMemories: coerceBool(cfg.codexMaterializeMemories) ?? true,
1955
+ codexMaterializeNamespace: typeof cfg.codexMaterializeNamespace === "string" && cfg.codexMaterializeNamespace.trim().length > 0 ? cfg.codexMaterializeNamespace.trim() : "auto",
1956
+ codexMaterializeMaxSummaryTokens: parseIntegerAtLeast(
1957
+ cfg.codexMaterializeMaxSummaryTokens,
1958
+ 4500,
1959
+ 0,
1960
+ "codexMaterializeMaxSummaryTokens"
1961
+ ),
1962
+ codexMaterializeRolloutRetentionDays: parseIntegerAtLeast(
1963
+ cfg.codexMaterializeRolloutRetentionDays,
1964
+ 30,
1965
+ 0,
1966
+ "codexMaterializeRolloutRetentionDays"
1967
+ ),
1968
+ codexMaterializeOnConsolidation: coerceBool(cfg.codexMaterializeOnConsolidation) ?? true,
1969
+ codexMaterializeOnSessionEnd: coerceBool(cfg.codexMaterializeOnSessionEnd) ?? true,
1970
+ // Codex CLI — marketplace integration (#418)
1971
+ codexMarketplaceEnabled: cfg.codexMarketplaceEnabled !== false,
1972
+ // default: true
1973
+ // Page-level versioning (issue #371). Issue #678 PR 2/4:
1974
+ // dreams.phases.deepSleep.* WINS over legacy keys.
1975
+ versioningEnabled: dreamsDeepSleep.enabled && dreamsDeepSleep.versioningEnabled,
1976
+ versioningMaxPerPage: dreamsDeepSleep.versioningMaxPerPage,
1977
+ versioningSidecarDir: typeof cfg.versioningSidecarDir === "string" && cfg.versioningSidecarDir.trim().length > 0 ? cfg.versioningSidecarDir.trim() : ".versions",
1978
+ // Binary file lifecycle management (#367)
1979
+ binaryLifecycleEnabled: cfg.binaryLifecycleEnabled === true,
1980
+ binaryLifecycleGracePeriodDays: typeof cfg.binaryLifecycleGracePeriodDays === "number" ? Math.max(0, Math.floor(cfg.binaryLifecycleGracePeriodDays)) : 7,
1981
+ binaryLifecycleBackendType: (() => {
1982
+ const valid = ["filesystem", "s3", "none"];
1983
+ const raw2 = cfg.binaryLifecycleBackendType;
1984
+ if (typeof raw2 === "string" && valid.includes(raw2)) {
1985
+ return raw2;
1986
+ }
1987
+ return "none";
1988
+ })(),
1989
+ binaryLifecycleBackendPath: typeof cfg.binaryLifecycleBackendPath === "string" ? cfg.binaryLifecycleBackendPath.trim() : "",
1990
+ // Codex citation parity (issue #379)
1991
+ citationsEnabled: cfg.citationsEnabled === true,
1992
+ citationsAutoDetect: cfg.citationsAutoDetect !== false,
1993
+ // External enrichment pipeline (issue #365)
1994
+ enrichmentEnabled: cfg.enrichmentEnabled === true,
1995
+ enrichmentAutoOnCreate: cfg.enrichmentAutoOnCreate === true,
1996
+ enrichmentMaxCandidatesPerEntity: typeof cfg.enrichmentMaxCandidatesPerEntity === "number" ? Math.max(0, Math.floor(cfg.enrichmentMaxCandidatesPerEntity)) : 20,
1997
+ // Memory extensions discovery (#382)
1998
+ memoryExtensionsEnabled: cfg.memoryExtensionsEnabled !== false,
1999
+ memoryExtensionsRoot: typeof cfg.memoryExtensionsRoot === "string" && cfg.memoryExtensionsRoot.trim().length > 0 ? cfg.memoryExtensionsRoot.trim() : ""
2000
+ };
2001
+ }
2002
+ function parseBriefingConfig(raw) {
2003
+ const entry = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
2004
+ const defaultFormat = entry.defaultFormat === "json" || entry.defaultFormat === "markdown" ? entry.defaultFormat : "markdown";
2005
+ const maxFollowupsRaw = typeof entry.maxFollowups === "number" && Number.isFinite(entry.maxFollowups) ? Math.floor(entry.maxFollowups) : 5;
2006
+ const maxFollowups = Math.max(0, Math.min(10, maxFollowupsRaw));
2007
+ return {
2008
+ enabled: entry.enabled !== false,
2009
+ defaultWindow: typeof entry.defaultWindow === "string" && entry.defaultWindow.trim().length > 0 ? entry.defaultWindow.trim() : "yesterday",
2010
+ defaultFormat,
2011
+ maxFollowups,
2012
+ calendarSource: typeof entry.calendarSource === "string" && entry.calendarSource.trim().length > 0 ? entry.calendarSource.trim() : null,
2013
+ saveByDefault: entry.saveByDefault === true,
2014
+ saveDir: typeof entry.saveDir === "string" && entry.saveDir.trim().length > 0 ? entry.saveDir.trim() : null,
2015
+ llmFollowups: entry.llmFollowups !== false
2016
+ };
2017
+ }
2018
+ function clampNonNegativeNumber(value) {
2019
+ if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
2020
+ return Math.max(0, Math.floor(value));
2021
+ }
2022
+ function coerceNonNegativeInt(value, fallback, keyName) {
2023
+ if (value === void 0 || value === null) return fallback;
2024
+ const coerced = coerceNumber(value);
2025
+ if (coerced === void 0 || coerced < 0) {
2026
+ const label = keyName ? ` (${keyName})` : "";
2027
+ throw new Error(
2028
+ `config value${label} must be a non-negative finite number; got ${JSON.stringify(value)}`
2029
+ );
2030
+ }
2031
+ return Math.floor(coerced);
2032
+ }
2033
+ function clampSurpriseThreshold(value, fallback) {
2034
+ if (value === void 0) return fallback;
2035
+ return Math.min(1, Math.max(0, value));
2036
+ }
2037
+ function clampSurpriseK(value, fallback) {
2038
+ if (value === void 0) return fallback;
2039
+ return Math.max(1, Math.floor(value));
2040
+ }
2041
+ function clampSurpriseRecentMemoryCount(value, fallback) {
2042
+ if (value === void 0) return fallback;
2043
+ return Math.max(0, Math.floor(value));
2044
+ }
2045
+ function clampSurpriseProbeTimeoutMs(value, fallback) {
2046
+ if (value === void 0) return fallback;
2047
+ return Math.max(1, Math.floor(value));
2048
+ }
2049
+ function parseRecallSectionEntry(raw) {
2050
+ const entry = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
2051
+ return {
2052
+ id: typeof entry.id === "string" ? entry.id.trim() : "",
2053
+ enabled: entry.enabled !== false,
2054
+ maxChars: entry.maxChars === null ? null : clampNonNegativeNumber(entry.maxChars),
2055
+ maxHints: clampNonNegativeNumber(entry.maxHints),
2056
+ maxSupportingFacts: clampNonNegativeNumber(entry.maxSupportingFacts),
2057
+ maxRelatedEntities: clampNonNegativeNumber(entry.maxRelatedEntities),
2058
+ consolidateTriggerLines: clampNonNegativeNumber(entry.consolidateTriggerLines),
2059
+ consolidateTargetLines: clampNonNegativeNumber(entry.consolidateTargetLines),
2060
+ maxEntities: clampNonNegativeNumber(entry.maxEntities),
2061
+ maxResults: clampNonNegativeNumber(entry.maxResults),
2062
+ recentTurns: clampNonNegativeNumber(entry.recentTurns),
2063
+ maxTurns: clampNonNegativeNumber(entry.maxTurns),
2064
+ maxTokens: clampNonNegativeNumber(entry.maxTokens),
2065
+ lookbackHours: clampNonNegativeNumber(entry.lookbackHours),
2066
+ maxCount: clampNonNegativeNumber(entry.maxCount),
2067
+ topK: clampNonNegativeNumber(entry.topK),
2068
+ timeoutMs: clampNonNegativeNumber(entry.timeoutMs),
2069
+ maxPatterns: clampNonNegativeNumber(entry.maxPatterns),
2070
+ maxRubrics: clampNonNegativeNumber(entry.maxRubrics),
2071
+ ...entry.forceGeneric === void 0 ? {} : { forceGeneric: coerceBool(entry.forceGeneric) === true }
2072
+ };
2073
+ }
2074
+ function buildDefaultRecallPipeline(cfg) {
2075
+ return [
2076
+ {
2077
+ id: "shared-context",
2078
+ enabled: cfg.sharedContextEnabled === true,
2079
+ maxChars: typeof cfg.sharedContextMaxInjectChars === "number" ? Math.max(0, Math.floor(cfg.sharedContextMaxInjectChars)) : 4e3
2080
+ },
2081
+ {
2082
+ id: "explicit-cue",
2083
+ enabled: coerceBool(cfg.explicitCueRecallEnabled) === true,
2084
+ maxChars: coerceNumber(cfg.explicitCueRecallMaxChars) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxChars))) : 2400,
2085
+ maxResults: coerceNumber(cfg.explicitCueRecallMaxReferences) !== void 0 ? Math.max(0, Math.floor(coerceNumber(cfg.explicitCueRecallMaxReferences))) : 24
2086
+ },
2087
+ {
2088
+ id: "targeted-facts",
2089
+ enabled: coerceBool(cfg.targetedFactRecallEnabled) === true,
2090
+ maxChars: parseIntegerAtLeast(cfg.targetedFactRecallMaxChars, 2400, 0, "targetedFactRecallMaxChars"),
2091
+ maxResults: parseIntegerAtLeast(cfg.targetedFactRecallMaxResults, 48, 0, "targetedFactRecallMaxResults"),
2092
+ maxTurns: parseIntegerAtLeast(cfg.targetedFactRecallScanWindowTurns, 8, 1, "targetedFactRecallScanWindowTurns"),
2093
+ maxTokens: parseIntegerAtLeast(cfg.targetedFactRecallScanWindowTokens, 12e3, 1, "targetedFactRecallScanWindowTokens")
2094
+ },
2095
+ {
2096
+ id: "focused-list",
2097
+ enabled: coerceBool(cfg.focusedListRecallEnabled) === true,
2098
+ maxChars: parseIntegerAtLeast(cfg.focusedListRecallMaxChars, 2600, 0, "focusedListRecallMaxChars"),
2099
+ maxResults: parseIntegerAtLeast(cfg.focusedListRecallMaxResults, 40, 0, "focusedListRecallMaxResults"),
2100
+ maxTurns: parseIntegerAtLeast(cfg.focusedListRecallScanWindowTurns, 64, 1, "focusedListRecallScanWindowTurns"),
2101
+ maxTokens: parseIntegerAtLeast(cfg.focusedListRecallScanWindowTokens, 14e3, 1, "focusedListRecallScanWindowTokens")
2102
+ },
2103
+ {
2104
+ id: "response-guidance",
2105
+ enabled: coerceBool(cfg.responseGuidanceRecallEnabled) === true,
2106
+ maxChars: parseIntegerAtLeast(cfg.responseGuidanceRecallMaxChars, 2400, 0, "responseGuidanceRecallMaxChars"),
2107
+ maxResults: parseIntegerAtLeast(cfg.responseGuidanceRecallMaxResults, 48, 0, "responseGuidanceRecallMaxResults"),
2108
+ maxTurns: parseIntegerAtLeast(cfg.responseGuidanceRecallScanWindowTurns, 64, 1, "responseGuidanceRecallScanWindowTurns"),
2109
+ maxTokens: parseIntegerAtLeast(cfg.responseGuidanceRecallScanWindowTokens, 16e3, 1, "responseGuidanceRecallScanWindowTokens")
2110
+ },
2111
+ {
2112
+ id: "event-order",
2113
+ enabled: coerceBool(cfg.eventOrderRecallEnabled) === true,
2114
+ maxChars: parseIntegerAtLeast(cfg.eventOrderRecallMaxChars, 2400, 0, "eventOrderRecallMaxChars"),
2115
+ maxResults: parseIntegerAtLeast(cfg.eventOrderRecallMaxResults, 24, 0, "eventOrderRecallMaxResults"),
2116
+ maxTurns: parseIntegerAtLeast(cfg.eventOrderRecallScanWindowTurns, 12, 1, "eventOrderRecallScanWindowTurns"),
2117
+ maxTokens: parseIntegerAtLeast(cfg.eventOrderRecallScanWindowTokens, 24e3, 1, "eventOrderRecallScanWindowTokens")
2118
+ },
2119
+ {
2120
+ id: "profile",
2121
+ enabled: true,
2122
+ consolidateTriggerLines: 100,
2123
+ consolidateTargetLines: 50
2124
+ },
2125
+ {
2126
+ id: "identity-continuity",
2127
+ enabled: cfg.identityContinuityEnabled === true
2128
+ },
2129
+ {
2130
+ id: "entity-retrieval",
2131
+ enabled: cfg.entityRetrievalEnabled !== false,
2132
+ maxChars: typeof cfg.entityRetrievalMaxChars === "number" ? Math.max(0, Math.floor(cfg.entityRetrievalMaxChars)) : 2400,
2133
+ maxHints: typeof cfg.entityRetrievalMaxHints === "number" ? Math.max(0, Math.floor(cfg.entityRetrievalMaxHints)) : 2,
2134
+ maxSupportingFacts: typeof cfg.entityRetrievalMaxSupportingFacts === "number" ? Math.max(0, Math.floor(cfg.entityRetrievalMaxSupportingFacts)) : 6,
2135
+ maxRelatedEntities: typeof cfg.entityRetrievalMaxRelatedEntities === "number" ? Math.max(0, Math.floor(cfg.entityRetrievalMaxRelatedEntities)) : 3,
2136
+ recentTurns: typeof cfg.entityRetrievalRecentTurns === "number" ? Math.max(0, Math.floor(cfg.entityRetrievalRecentTurns)) : 6
2137
+ },
2138
+ {
2139
+ id: "knowledge-index",
2140
+ enabled: cfg.knowledgeIndexEnabled !== false,
2141
+ maxChars: typeof cfg.knowledgeIndexMaxChars === "number" ? Math.max(0, Math.floor(cfg.knowledgeIndexMaxChars)) : 4e3,
2142
+ maxEntities: typeof cfg.knowledgeIndexMaxEntities === "number" ? Math.max(0, Math.floor(cfg.knowledgeIndexMaxEntities)) : 40
2143
+ },
2144
+ { id: "verbatim-artifacts", enabled: cfg.verbatimArtifactsEnabled === true },
2145
+ {
2146
+ id: "procedure-recall",
2147
+ // Default-on since issue #567 PR 4/5: the master `procedural.enabled`
2148
+ // gate now defaults to `true` when the key is omitted, so the recall
2149
+ // pipeline must stay in sync. Explicit `false` (or any coerceBool
2150
+ // falsy variant) still disables recall injection.
2151
+ //
2152
+ // CLAUDE.md rule 48 (least-privileged defaults) + Cursor review on #609:
2153
+ // never fail open on unrecognized values. Only `coerced === true` or
2154
+ // the "key omitted" path enables the section. `parseConfig` throws
2155
+ // on invalid values upstream, so this branch only ever sees boolean
2156
+ // results — `coerced === undefined` should never happen in practice,
2157
+ // but defense-in-depth keeps the section disabled if it ever does.
2158
+ enabled: (() => {
2159
+ const proceduralRaw = typeof cfg.procedural === "object" && cfg.procedural !== null && !Array.isArray(cfg.procedural) ? cfg.procedural : void 0;
2160
+ if (proceduralRaw === void 0) return true;
2161
+ const rawEnabled = proceduralRaw.enabled;
2162
+ if (rawEnabled === void 0) return true;
2163
+ return coerceBool(rawEnabled) === true;
2164
+ })(),
2165
+ maxChars: 2400
2166
+ },
2167
+ { id: "memory-boxes", enabled: cfg.memoryBoxesEnabled === true },
2168
+ { id: "temporal-memory-tree", enabled: cfg.temporalMemoryTreeEnabled === true },
2169
+ { id: "lcm-compressed-history", enabled: cfg.lcmEnabled === true },
2170
+ {
2171
+ id: "objective-state",
2172
+ enabled: cfg.objectiveStateRecallEnabled === true,
2173
+ maxResults: 4,
2174
+ maxChars: 1800
2175
+ },
2176
+ {
2177
+ id: "causal-trajectories",
2178
+ enabled: cfg.causalTrajectoryRecallEnabled === true,
2179
+ maxResults: 3,
2180
+ maxChars: 2200
2181
+ },
2182
+ {
2183
+ id: "trust-zones",
2184
+ enabled: cfg.trustZoneRecallEnabled === true,
2185
+ maxResults: 3,
2186
+ maxChars: 1800
2187
+ },
2188
+ {
2189
+ id: "harmonic-retrieval",
2190
+ enabled: cfg.harmonicRetrievalEnabled === true,
2191
+ maxResults: 3,
2192
+ maxChars: 2200
2193
+ },
2194
+ {
2195
+ id: "verified-episodes",
2196
+ enabled: cfg.verifiedRecallEnabled === true,
2197
+ maxResults: 3,
2198
+ maxChars: 1800
2199
+ },
2200
+ {
2201
+ id: "verified-rules",
2202
+ enabled: cfg.semanticRuleVerificationEnabled === true,
2203
+ maxResults: 3,
2204
+ maxChars: 1800
2205
+ },
2206
+ {
2207
+ id: "work-products",
2208
+ enabled: cfg.workProductRecallEnabled === true,
2209
+ maxResults: 3,
2210
+ maxChars: 1800
2211
+ },
2212
+ {
2213
+ id: "memories",
2214
+ enabled: true,
2215
+ maxResults: typeof cfg.qmdMaxResults === "number" ? Math.max(0, Math.floor(cfg.qmdMaxResults)) : 8
2216
+ },
2217
+ {
2218
+ id: "compression-guidelines",
2219
+ enabled: cfg.compressionGuidelineLearningEnabled === true
2220
+ },
2221
+ {
2222
+ id: "native-knowledge",
2223
+ enabled: cfg.nativeKnowledge && typeof cfg.nativeKnowledge === "object" ? cfg.nativeKnowledge.enabled === true : false,
2224
+ maxResults: cfg.nativeKnowledge && typeof cfg.nativeKnowledge === "object" && typeof cfg.nativeKnowledge.maxResults === "number" ? Math.max(0, Math.floor(cfg.nativeKnowledge.maxResults)) : 4,
2225
+ maxChars: cfg.nativeKnowledge && typeof cfg.nativeKnowledge === "object" && typeof cfg.nativeKnowledge.maxChars === "number" ? Math.max(0, Math.floor(cfg.nativeKnowledge.maxChars)) : 2400
2226
+ },
2227
+ {
2228
+ id: "transcript",
2229
+ enabled: cfg.transcriptEnabled !== false,
2230
+ maxTurns: typeof cfg.maxTranscriptTurns === "number" ? Math.max(0, Math.floor(cfg.maxTranscriptTurns)) : 50,
2231
+ maxTokens: typeof cfg.maxTranscriptTokens === "number" ? Math.max(0, Math.floor(cfg.maxTranscriptTokens)) : 1e3,
2232
+ lookbackHours: typeof cfg.transcriptRecallHours === "number" ? Math.max(0, Math.floor(cfg.transcriptRecallHours)) : 12
2233
+ },
2234
+ {
2235
+ id: "summaries",
2236
+ enabled: cfg.hourlySummariesEnabled !== false,
2237
+ maxCount: typeof cfg.maxSummaryCount === "number" ? Math.max(0, Math.floor(cfg.maxSummaryCount)) : 6,
2238
+ lookbackHours: typeof cfg.summaryRecallHours === "number" ? Math.max(0, Math.floor(cfg.summaryRecallHours)) : 24
2239
+ },
2240
+ {
2241
+ id: "conversation-recall",
2242
+ enabled: cfg.conversationIndexEnabled === true,
2243
+ topK: typeof cfg.conversationRecallTopK === "number" ? Math.max(0, Math.floor(cfg.conversationRecallTopK)) : 3,
2244
+ maxChars: typeof cfg.conversationRecallMaxChars === "number" ? Math.max(0, Math.floor(cfg.conversationRecallMaxChars)) : 2500,
2245
+ timeoutMs: typeof cfg.conversationRecallTimeoutMs === "number" ? Math.max(0, Math.floor(cfg.conversationRecallTimeoutMs)) : 800
2246
+ },
2247
+ {
2248
+ id: "compounding",
2249
+ enabled: cfg.compoundingEnabled === true && cfg.compoundingInjectEnabled !== false,
2250
+ maxPatterns: 40,
2251
+ maxRubrics: 4
2252
+ },
2253
+ { id: "questions", enabled: cfg.injectQuestions === true }
2254
+ ];
2255
+ }
2256
+ function buildRecallPipelineConfig(cfg) {
2257
+ const maxMemoryTokens = typeof cfg.maxMemoryTokens === "number" ? Math.max(0, Math.floor(cfg.maxMemoryTokens)) : 2e3;
2258
+ const recallBudgetCharsRaw = clampNonNegativeNumber(cfg.recallBudgetChars);
2259
+ const recallBudgetChars = recallBudgetCharsRaw ?? maxMemoryTokens * 4;
2260
+ const rawPipeline = cfg.recallPipeline;
2261
+ const pipeline = Array.isArray(rawPipeline) ? rawPipeline.map(parseRecallSectionEntry).filter((entry) => entry.id.length > 0) : buildDefaultRecallPipeline(cfg);
2262
+ return { recallBudgetChars, pipeline };
2263
+ }
2264
+
2265
+ export {
2266
+ isOpenaiApiKeyDisabled,
2267
+ resolveEnvVars,
2268
+ DEFAULT_REASONING_MODEL,
2269
+ VALID_MEMORY_CATEGORIES,
2270
+ parseConfig
2271
+ };
2272
+ //# sourceMappingURL=chunk-2QR3XXIC.js.map