@remnic/core 1.0.3 → 1.1.1

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 (323) hide show
  1. package/dist/abort-error.d.ts +32 -0
  2. package/dist/abort-error.js +11 -0
  3. package/dist/access-audit.d.ts +56 -0
  4. package/dist/access-audit.js +9 -0
  5. package/dist/access-audit.js.map +1 -0
  6. package/dist/access-cli.js +72 -54
  7. package/dist/access-cli.js.map +1 -1
  8. package/dist/access-http.d.ts +16 -8
  9. package/dist/access-http.js +25 -17
  10. package/dist/access-mcp.d.ts +16 -8
  11. package/dist/access-mcp.js +28 -6
  12. package/dist/access-schema.d.ts +130 -39
  13. package/dist/access-schema.js +5 -1
  14. package/dist/access-service-Br8ZydTK.d.ts +827 -0
  15. package/dist/access-service.d.ts +20 -660
  16. package/dist/access-service.js +22 -14
  17. package/dist/bootstrap.d.ts +6 -3
  18. package/dist/briefing.d.ts +1 -0
  19. package/dist/briefing.js +6 -5
  20. package/dist/buffer-surprise-report.d.ts +70 -0
  21. package/dist/buffer-surprise-report.js +7 -0
  22. package/dist/buffer-surprise-report.js.map +1 -0
  23. package/dist/buffer-surprise.d.ts +98 -0
  24. package/dist/buffer-surprise.js +11 -0
  25. package/dist/buffer-surprise.js.map +1 -0
  26. package/dist/buffer.d.ts +100 -2
  27. package/dist/buffer.js +1 -1
  28. package/dist/calibration.js +5 -5
  29. package/dist/causal-behavior.js +4 -4
  30. package/dist/causal-chain.js +2 -2
  31. package/dist/causal-consolidation.js +17 -16
  32. package/dist/causal-consolidation.js.map +1 -1
  33. package/dist/causal-retrieval.js +4 -4
  34. package/dist/causal-trajectory.js +1 -1
  35. package/dist/{chunk-QNJMBKFK.js → chunk-2LGMW3DJ.js} +3 -2
  36. package/dist/chunk-2LGMW3DJ.js.map +1 -0
  37. package/dist/{chunk-QDYXG4CS.js → chunk-3FPTCC3Z.js} +4 -3
  38. package/dist/chunk-3FPTCC3Z.js.map +1 -0
  39. package/dist/chunk-3GPTTA4J.js +57 -0
  40. package/dist/chunk-3GPTTA4J.js.map +1 -0
  41. package/dist/{chunk-QKAH5B6E.js → chunk-3GXCSUXR.js} +94 -6
  42. package/dist/chunk-3GXCSUXR.js.map +1 -0
  43. package/dist/{chunk-POBPGDWI.js → chunk-3OGMS3PE.js} +2 -2
  44. package/dist/chunk-54V4BZWP.js +139 -0
  45. package/dist/chunk-54V4BZWP.js.map +1 -0
  46. package/dist/chunk-5JRF2PZA.js +67 -0
  47. package/dist/chunk-5JRF2PZA.js.map +1 -0
  48. package/dist/chunk-64NJRYU2.js +332 -0
  49. package/dist/chunk-64NJRYU2.js.map +1 -0
  50. package/dist/chunk-6AUUAZEX.js +150 -0
  51. package/dist/chunk-6AUUAZEX.js.map +1 -0
  52. package/dist/{chunk-HITJFT7E.js → chunk-7I7FKFZH.js} +28 -21
  53. package/dist/chunk-7I7FKFZH.js.map +1 -0
  54. package/dist/chunk-AJU4PJGY.js +126 -0
  55. package/dist/chunk-AJU4PJGY.js.map +1 -0
  56. package/dist/chunk-ASAITVLA.js +64 -0
  57. package/dist/chunk-ASAITVLA.js.map +1 -0
  58. package/dist/{chunk-X4WESCKA.js → chunk-B5WXLVDY.js} +187 -6
  59. package/dist/chunk-B5WXLVDY.js.map +1 -0
  60. package/dist/{chunk-RCICHSHL.js → chunk-BGJGXLZ7.js} +111 -2
  61. package/dist/{chunk-RCICHSHL.js.map → chunk-BGJGXLZ7.js.map} +1 -1
  62. package/dist/{chunk-OJFGVJS6.js → chunk-BK2EFTE2.js} +319 -18
  63. package/dist/chunk-BK2EFTE2.js.map +1 -0
  64. package/dist/chunk-C4SQJZAF.js +486 -0
  65. package/dist/chunk-C4SQJZAF.js.map +1 -0
  66. package/dist/{chunk-GJQPH5G3.js → chunk-CUPFXL3J.js} +2 -2
  67. package/dist/chunk-DF3RVK3X.js +119 -0
  68. package/dist/chunk-DF3RVK3X.js.map +1 -0
  69. package/dist/{chunk-PMB3WGDL.js → chunk-DFTTJYSO.js} +167 -7
  70. package/dist/chunk-DFTTJYSO.js.map +1 -0
  71. package/dist/chunk-DGVM5SFL.js +69 -0
  72. package/dist/chunk-DGVM5SFL.js.map +1 -0
  73. package/dist/chunk-EIR5VLIH.js +90 -0
  74. package/dist/chunk-EIR5VLIH.js.map +1 -0
  75. package/dist/{chunk-PAORGQRI.js → chunk-EPQJM2GC.js} +37 -23
  76. package/dist/chunk-EPQJM2GC.js.map +1 -0
  77. package/dist/{chunk-POMSFKTB.js → chunk-F5VP6YCB.js} +368 -10
  78. package/dist/chunk-F5VP6YCB.js.map +1 -0
  79. package/dist/{chunk-6ZH4TU6I.js → chunk-FAAFWE4G.js} +2 -1
  80. package/dist/chunk-FAAFWE4G.js.map +1 -0
  81. package/dist/{chunk-74JR4N5J.js → chunk-FVA6TGI3.js} +2 -2
  82. package/dist/chunk-GDFS42HT.js +206 -0
  83. package/dist/chunk-GDFS42HT.js.map +1 -0
  84. package/dist/{chunk-BKQJBXXX.js → chunk-GGD5W7TB.js} +2 -2
  85. package/dist/chunk-GGD5W7TB.js.map +1 -0
  86. package/dist/{chunk-V7XCAHIB.js → chunk-GKFXUTJ2.js} +508 -26
  87. package/dist/chunk-GKFXUTJ2.js.map +1 -0
  88. package/dist/{chunk-NSB3WSYS.js → chunk-HK3FGIEW.js} +278 -3
  89. package/dist/chunk-HK3FGIEW.js.map +1 -0
  90. package/dist/{chunk-AAI7JARD.js → chunk-HMDCOMYU.js} +8 -11
  91. package/dist/chunk-HMDCOMYU.js.map +1 -0
  92. package/dist/chunk-IISBCCWR.js +52 -0
  93. package/dist/chunk-IISBCCWR.js.map +1 -0
  94. package/dist/{chunk-YFYL2SIJ.js → chunk-INXV5JBT.js} +290 -46
  95. package/dist/chunk-INXV5JBT.js.map +1 -0
  96. package/dist/chunk-JBMSGZEQ.js +441 -0
  97. package/dist/chunk-JBMSGZEQ.js.map +1 -0
  98. package/dist/{chunk-UPMD5XND.js → chunk-JL2PU6AI.js} +16 -5
  99. package/dist/chunk-JL2PU6AI.js.map +1 -0
  100. package/dist/{chunk-J4IYOZZ5.js → chunk-JXS5PDQ7.js} +3 -1
  101. package/dist/chunk-JXS5PDQ7.js.map +1 -0
  102. package/dist/{chunk-AYPYCLR7.js → chunk-KUB6JU6H.js} +4 -4
  103. package/dist/chunk-KVBLZUKV.js +173 -0
  104. package/dist/chunk-KVBLZUKV.js.map +1 -0
  105. package/dist/chunk-LBLXEFWK.js +51 -0
  106. package/dist/chunk-LBLXEFWK.js.map +1 -0
  107. package/dist/{chunk-U2IQTSBY.js → chunk-LTCGGW2D.js} +1 -1
  108. package/dist/chunk-LTCGGW2D.js.map +1 -0
  109. package/dist/{chunk-UEYA6UC7.js → chunk-NZLQTHS5.js} +25 -2
  110. package/dist/chunk-NZLQTHS5.js.map +1 -0
  111. package/dist/chunk-PVGDJXVK.js +21 -0
  112. package/dist/chunk-PVGDJXVK.js.map +1 -0
  113. package/dist/chunk-PVPWZSSI.js +37 -0
  114. package/dist/chunk-PVPWZSSI.js.map +1 -0
  115. package/dist/{chunk-4NRAJUDS.js → chunk-RBBWYEFJ.js} +1 -1
  116. package/dist/chunk-RFYAYKTD.js +146 -0
  117. package/dist/chunk-RFYAYKTD.js.map +1 -0
  118. package/dist/{chunk-JROGC36Y.js → chunk-RGLL5SPU.js} +2 -2
  119. package/dist/{chunk-2VFW5K5U.js → chunk-S3EEFKNY.js} +103 -65
  120. package/dist/chunk-S3EEFKNY.js.map +1 -0
  121. package/dist/chunk-SOBJ6NEY.js +18 -0
  122. package/dist/chunk-SOBJ6NEY.js.map +1 -0
  123. package/dist/{chunk-MYQWXITD.js → chunk-SPI27QT6.js} +2 -2
  124. package/dist/chunk-TVVEYCNW.js +65 -0
  125. package/dist/chunk-TVVEYCNW.js.map +1 -0
  126. package/dist/chunk-ULYOGL6R.js +322 -0
  127. package/dist/chunk-ULYOGL6R.js.map +1 -0
  128. package/dist/{chunk-S4LX5EBI.js → chunk-VBVG2M5G.js} +64 -10
  129. package/dist/chunk-VBVG2M5G.js.map +1 -0
  130. package/dist/{chunk-KWP7T3DP.js → chunk-VDX363PS.js} +2 -2
  131. package/dist/{chunk-XMGSSBFX.js → chunk-VYM3VWOF.js} +1560 -244
  132. package/dist/chunk-VYM3VWOF.js.map +1 -0
  133. package/dist/{chunk-MTLYEMJB.js → chunk-WCLICCGB.js} +18 -3
  134. package/dist/chunk-WCLICCGB.js.map +1 -0
  135. package/dist/{chunk-ECKDIK5F.js → chunk-WVVA7F5A.js} +2 -2
  136. package/dist/chunk-X6GF3FX2.js +26 -0
  137. package/dist/chunk-X6GF3FX2.js.map +1 -0
  138. package/dist/{chunk-3QFQGRHO.js → chunk-XMHBH5H6.js} +4 -4
  139. package/dist/{chunk-KEG4GNGI.js → chunk-XZ2TIKGC.js} +38 -8
  140. package/dist/chunk-XZ2TIKGC.js.map +1 -0
  141. package/dist/chunk-Y4FHOFJ2.js +140 -0
  142. package/dist/chunk-Y4FHOFJ2.js.map +1 -0
  143. package/dist/chunk-YNB73F22.js +137 -0
  144. package/dist/chunk-YNB73F22.js.map +1 -0
  145. package/dist/{chunk-7PA4OZEU.js → chunk-YNQKWQT4.js} +55 -30
  146. package/dist/chunk-YNQKWQT4.js.map +1 -0
  147. package/dist/chunk-ZAIM4TUE.js +488 -0
  148. package/dist/chunk-ZAIM4TUE.js.map +1 -0
  149. package/dist/{chunk-BTY5RRRF.js → chunk-ZEM3OK2K.js} +5 -5
  150. package/dist/chunk-ZZTOURJI.js +91 -0
  151. package/dist/chunk-ZZTOURJI.js.map +1 -0
  152. package/dist/{cli-DwIBnp2g.d.ts → cli-BkeRaYfk.d.ts} +2 -2
  153. package/dist/cli.d.ts +13 -5
  154. package/dist/cli.js +45 -33
  155. package/dist/config.js +1 -1
  156. package/dist/consolidation-operator.d.ts +41 -0
  157. package/dist/consolidation-operator.js +11 -0
  158. package/dist/consolidation-operator.js.map +1 -0
  159. package/dist/consolidation-provenance-check.d.ts +68 -0
  160. package/dist/consolidation-provenance-check.js +9 -0
  161. package/dist/consolidation-provenance-check.js.map +1 -0
  162. package/dist/consolidation-undo.d.ts +123 -0
  163. package/dist/consolidation-undo.js +426 -0
  164. package/dist/consolidation-undo.js.map +1 -0
  165. package/dist/contradiction-review-WIUBAR52.js +21 -0
  166. package/dist/contradiction-review-WIUBAR52.js.map +1 -0
  167. package/dist/contradiction-scan-E3GJTI4F.js +412 -0
  168. package/dist/contradiction-scan-E3GJTI4F.js.map +1 -0
  169. package/dist/cross-namespace-budget.d.ts +133 -0
  170. package/dist/cross-namespace-budget.js +9 -0
  171. package/dist/cross-namespace-budget.js.map +1 -0
  172. package/dist/direct-answer-wiring.d.ts +77 -0
  173. package/dist/direct-answer-wiring.js +10 -0
  174. package/dist/direct-answer-wiring.js.map +1 -0
  175. package/dist/direct-answer.d.ts +106 -0
  176. package/dist/direct-answer.js +10 -0
  177. package/dist/direct-answer.js.map +1 -0
  178. package/dist/{engine-X7X3AAG3.js → engine-F3GOXGE5.js} +7 -6
  179. package/dist/engine-F3GOXGE5.js.map +1 -0
  180. package/dist/entity-retrieval.d.ts +1 -0
  181. package/dist/entity-retrieval.js +6 -5
  182. package/dist/explicit-capture.d.ts +6 -3
  183. package/dist/explicit-capture.js +2 -2
  184. package/dist/extraction-judge-telemetry.d.ts +113 -0
  185. package/dist/extraction-judge-telemetry.js +14 -0
  186. package/dist/extraction-judge-telemetry.js.map +1 -0
  187. package/dist/extraction-judge-training.d.ts +85 -0
  188. package/dist/extraction-judge-training.js +16 -0
  189. package/dist/extraction-judge-training.js.map +1 -0
  190. package/dist/extraction-judge.d.ts +124 -2
  191. package/dist/extraction-judge.js +11 -1
  192. package/dist/extraction.js +7 -6
  193. package/dist/fallback-llm.d.ts +11 -2
  194. package/dist/fallback-llm.js +2 -2
  195. package/dist/graph-recall.d.ts +100 -0
  196. package/dist/graph-recall.js +8 -0
  197. package/dist/graph-recall.js.map +1 -0
  198. package/dist/graph-retrieval.d.ts +271 -0
  199. package/dist/graph-retrieval.js +21 -0
  200. package/dist/graph-retrieval.js.map +1 -0
  201. package/dist/harmonic-retrieval.js +2 -1
  202. package/dist/importance.js +1 -1
  203. package/dist/index.d.ts +589 -138
  204. package/dist/index.js +531 -403
  205. package/dist/index.js.map +1 -1
  206. package/dist/intent.js +1 -1
  207. package/dist/local-llm.d.ts +10 -3
  208. package/dist/local-llm.js +1 -1
  209. package/dist/memory-worth-bench.d.ts +51 -0
  210. package/dist/memory-worth-bench.js +131 -0
  211. package/dist/memory-worth-bench.js.map +1 -0
  212. package/dist/memory-worth-filter.d.ts +128 -0
  213. package/dist/memory-worth-filter.js +10 -0
  214. package/dist/memory-worth-filter.js.map +1 -0
  215. package/dist/memory-worth-outcomes.d.ts +118 -0
  216. package/dist/memory-worth-outcomes.js +9 -0
  217. package/dist/memory-worth-outcomes.js.map +1 -0
  218. package/dist/memory-worth.d.ts +102 -0
  219. package/dist/memory-worth.js +7 -0
  220. package/dist/memory-worth.js.map +1 -0
  221. package/dist/operator-toolkit.d.ts +40 -1
  222. package/dist/operator-toolkit.js +24 -14
  223. package/dist/{orchestrator-B9kwlCep.d.ts → orchestrator-CmJ-NTdJ.d.ts} +254 -10
  224. package/dist/orchestrator.d.ts +6 -3
  225. package/dist/orchestrator.js +59 -48
  226. package/dist/page-versioning.d.ts +12 -1
  227. package/dist/page-versioning.js +5 -3
  228. package/dist/{port-C1GZFv8h.d.ts → port-BADbLZU5.d.ts} +2 -2
  229. package/dist/qmd-recall-cache.d.ts +1 -1
  230. package/dist/qmd.d.ts +5 -3
  231. package/dist/qmd.js +2 -1
  232. package/dist/reasoning-trace-recall.d.ts +90 -0
  233. package/dist/reasoning-trace-recall.js +13 -0
  234. package/dist/reasoning-trace-recall.js.map +1 -0
  235. package/dist/reasoning-trace-types.d.ts +54 -0
  236. package/dist/reasoning-trace-types.js +17 -0
  237. package/dist/reasoning-trace-types.js.map +1 -0
  238. package/dist/recall-audit-anomaly.d.ts +112 -0
  239. package/dist/recall-audit-anomaly.js +11 -0
  240. package/dist/recall-audit-anomaly.js.map +1 -0
  241. package/dist/recall-audit.js +5 -44
  242. package/dist/recall-audit.js.map +1 -1
  243. package/dist/recall-explain-renderer.d.ts +49 -0
  244. package/dist/recall-explain-renderer.js +18 -0
  245. package/dist/recall-explain-renderer.js.map +1 -0
  246. package/dist/recall-state.d.ts +39 -1
  247. package/dist/recall-state.js +1 -1
  248. package/dist/recall-xray-cli.d.ts +40 -0
  249. package/dist/recall-xray-cli.js +11 -0
  250. package/dist/recall-xray-cli.js.map +1 -0
  251. package/dist/recall-xray-renderer.d.ts +44 -0
  252. package/dist/recall-xray-renderer.js +18 -0
  253. package/dist/recall-xray-renderer.js.map +1 -0
  254. package/dist/recall-xray.d.ts +179 -0
  255. package/dist/recall-xray.js +13 -0
  256. package/dist/recall-xray.js.map +1 -0
  257. package/dist/resolution-QBTDHTG7.js +100 -0
  258. package/dist/resolution-QBTDHTG7.js.map +1 -0
  259. package/dist/resolve-provider-secret.d.ts +24 -1
  260. package/dist/resolve-provider-secret.js +3 -1
  261. package/dist/resume-bundles.js +6 -6
  262. package/dist/retrieval-agents.d.ts +1 -1
  263. package/dist/retrieval-tiers.d.ts +17 -0
  264. package/dist/retrieval-tiers.js +9 -0
  265. package/dist/retrieval-tiers.js.map +1 -0
  266. package/dist/schemas.d.ts +301 -45
  267. package/dist/schemas.js +1 -1
  268. package/dist/{semantic-consolidation-DrvSYRdB.d.ts → semantic-consolidation-CxJU6MJk.d.ts} +62 -1
  269. package/dist/semantic-consolidation.d.ts +2 -1
  270. package/dist/semantic-consolidation.js +20 -6
  271. package/dist/semantic-rule-promotion.js +6 -5
  272. package/dist/semantic-rule-verifier.js +6 -5
  273. package/dist/storage.d.ts +82 -1
  274. package/dist/storage.js +5 -4
  275. package/dist/summarizer.js +4 -4
  276. package/dist/temporal-supersession.d.ts +1 -0
  277. package/dist/tier-migration.d.ts +2 -1
  278. package/dist/types-DJhqDJUV.d.ts +50 -0
  279. package/dist/types.d.ts +309 -3
  280. package/dist/types.js +1 -1
  281. package/dist/verified-recall.js +6 -5
  282. package/package.json +1 -1
  283. package/dist/chunk-2VFW5K5U.js.map +0 -1
  284. package/dist/chunk-6ZH4TU6I.js.map +0 -1
  285. package/dist/chunk-7PA4OZEU.js.map +0 -1
  286. package/dist/chunk-AAI7JARD.js.map +0 -1
  287. package/dist/chunk-BKQJBXXX.js.map +0 -1
  288. package/dist/chunk-HITJFT7E.js.map +0 -1
  289. package/dist/chunk-J4IYOZZ5.js.map +0 -1
  290. package/dist/chunk-KEG4GNGI.js.map +0 -1
  291. package/dist/chunk-LAYN4LDC.js +0 -267
  292. package/dist/chunk-LAYN4LDC.js.map +0 -1
  293. package/dist/chunk-MTLYEMJB.js.map +0 -1
  294. package/dist/chunk-NSB3WSYS.js.map +0 -1
  295. package/dist/chunk-OJFGVJS6.js.map +0 -1
  296. package/dist/chunk-PAORGQRI.js.map +0 -1
  297. package/dist/chunk-PMB3WGDL.js.map +0 -1
  298. package/dist/chunk-POMSFKTB.js.map +0 -1
  299. package/dist/chunk-QDYXG4CS.js.map +0 -1
  300. package/dist/chunk-QKAH5B6E.js.map +0 -1
  301. package/dist/chunk-QNJMBKFK.js.map +0 -1
  302. package/dist/chunk-S4LX5EBI.js.map +0 -1
  303. package/dist/chunk-U2IQTSBY.js.map +0 -1
  304. package/dist/chunk-UEYA6UC7.js.map +0 -1
  305. package/dist/chunk-UPMD5XND.js.map +0 -1
  306. package/dist/chunk-UVJFDP7P.js +0 -202
  307. package/dist/chunk-UVJFDP7P.js.map +0 -1
  308. package/dist/chunk-V7XCAHIB.js.map +0 -1
  309. package/dist/chunk-X4WESCKA.js.map +0 -1
  310. package/dist/chunk-XMGSSBFX.js.map +0 -1
  311. package/dist/chunk-YFYL2SIJ.js.map +0 -1
  312. /package/dist/{engine-X7X3AAG3.js.map → abort-error.js.map} +0 -0
  313. /package/dist/{chunk-POBPGDWI.js.map → chunk-3OGMS3PE.js.map} +0 -0
  314. /package/dist/{chunk-GJQPH5G3.js.map → chunk-CUPFXL3J.js.map} +0 -0
  315. /package/dist/{chunk-74JR4N5J.js.map → chunk-FVA6TGI3.js.map} +0 -0
  316. /package/dist/{chunk-AYPYCLR7.js.map → chunk-KUB6JU6H.js.map} +0 -0
  317. /package/dist/{chunk-4NRAJUDS.js.map → chunk-RBBWYEFJ.js.map} +0 -0
  318. /package/dist/{chunk-JROGC36Y.js.map → chunk-RGLL5SPU.js.map} +0 -0
  319. /package/dist/{chunk-MYQWXITD.js.map → chunk-SPI27QT6.js.map} +0 -0
  320. /package/dist/{chunk-KWP7T3DP.js.map → chunk-VDX363PS.js.map} +0 -0
  321. /package/dist/{chunk-ECKDIK5F.js.map → chunk-WVVA7F5A.js.map} +0 -0
  322. /package/dist/{chunk-3QFQGRHO.js.map → chunk-XMHBH5H6.js.map} +0 -0
  323. /package/dist/{chunk-BTY5RRRF.js.map → chunk-ZEM3OK2K.js.map} +0 -0
@@ -99,6 +99,31 @@ function normalizeMemoryRelativeDir(raw, fallback) {
99
99
  const normalized = trimmed.replace(/\\/g, "/").split("/").filter((segment) => segment.length > 0 && segment !== "." && segment !== "..").join("/");
100
100
  return normalized.length > 0 ? normalized : fallback;
101
101
  }
102
+ function parseContradictionScanConfig(raw) {
103
+ if (!raw || typeof raw !== "object") {
104
+ return {
105
+ enabled: false,
106
+ similarityFloor: 0.82,
107
+ topicOverlapFloor: 0.4,
108
+ maxPairsPerRun: 500,
109
+ cooldownDays: 14,
110
+ autoMergeDuplicates: false
111
+ };
112
+ }
113
+ const src = raw;
114
+ const simFloor = coerceNumber(src.similarityFloor) ?? 0.82;
115
+ const topicFloor = coerceNumber(src.topicOverlapFloor) ?? 0.4;
116
+ const maxPairs = coerceNumber(src.maxPairsPerRun) ?? 500;
117
+ const cooldown = coerceNumber(src.cooldownDays) ?? 14;
118
+ return {
119
+ enabled: coerceBool(src.enabled) === true,
120
+ similarityFloor: Math.min(1, Math.max(0, simFloor)),
121
+ topicOverlapFloor: Math.min(1, Math.max(0, topicFloor)),
122
+ maxPairsPerRun: Math.max(1, maxPairs),
123
+ cooldownDays: Math.max(0, cooldown),
124
+ autoMergeDuplicates: coerceBool(src.autoMergeDuplicates) === true
125
+ };
126
+ }
102
127
  function parseSemanticChunkingConfig(raw) {
103
128
  if (!raw || typeof raw !== "object") return {};
104
129
  const src = raw;
@@ -135,7 +160,8 @@ var VALID_MEMORY_CATEGORIES = /* @__PURE__ */ new Set([
135
160
  "moment",
136
161
  "skill",
137
162
  "rule",
138
- "procedure"
163
+ "procedure",
164
+ "reasoning_trace"
139
165
  ]);
140
166
  var DEFAULT_BEHAVIOR_LOOP_PROTECTED_PARAMS = [
141
167
  "maxMemoryTokens",
@@ -167,7 +193,14 @@ var MEMORY_OS_PRESETS = {
167
193
  compressionGuidelineSemanticRefinementEnabled: false,
168
194
  maxProactiveQuestionsPerExtraction: 0,
169
195
  maxCompressionTokensPerHour: 0,
170
- behaviorLoopAutoTuneEnabled: false
196
+ behaviorLoopAutoTuneEnabled: false,
197
+ // Issue #567 PR 4/5 flipped `procedural.enabled` default to `true`.
198
+ // The conservative preset intentionally keeps the feature OFF to
199
+ // match its restrictive intent (no proactive extraction, no
200
+ // compression guideline learning, etc.). Users who want procedural
201
+ // memory on a conservative preset must set `procedural.enabled: true`
202
+ // explicitly.
203
+ procedural: { enabled: false }
171
204
  },
172
205
  balanced: {
173
206
  maxMemoryTokens: 2e3,
@@ -249,11 +282,23 @@ function resolveMemoryOsPreset(value) {
249
282
  function parseConfig(raw) {
250
283
  const baseCfg = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
251
284
  const memoryOsPreset = resolveMemoryOsPreset(baseCfg.memoryOsPreset);
252
- const cfg = memoryOsPreset ? {
253
- ...MEMORY_OS_PRESETS[memoryOsPreset],
254
- ...baseCfg,
255
- memoryOsPreset
256
- } : baseCfg;
285
+ let cfg;
286
+ if (memoryOsPreset) {
287
+ const preset = MEMORY_OS_PRESETS[memoryOsPreset];
288
+ const presetProcedural = preset.procedural && typeof preset.procedural === "object" && !Array.isArray(preset.procedural) ? preset.procedural : void 0;
289
+ const baseProcedural = baseCfg.procedural && typeof baseCfg.procedural === "object" && !Array.isArray(baseCfg.procedural) ? baseCfg.procedural : void 0;
290
+ const mergedProcedural = presetProcedural && baseProcedural ? { ...presetProcedural, ...baseProcedural } : baseProcedural ?? presetProcedural;
291
+ cfg = {
292
+ ...preset,
293
+ ...baseCfg,
294
+ memoryOsPreset
295
+ };
296
+ if (mergedProcedural !== void 0) {
297
+ cfg.procedural = mergedProcedural;
298
+ }
299
+ } else {
300
+ cfg = baseCfg;
301
+ }
257
302
  let apiKey;
258
303
  if (typeof cfg.openaiApiKey === "string" && cfg.openaiApiKey.length > 0) {
259
304
  apiKey = resolveEnvVars(cfg.openaiApiKey);
@@ -302,18 +347,52 @@ function parseConfig(raw) {
302
347
  ) ? rawCodexCompat.compactionFlushMode : "auto",
303
348
  fingerprintDedup: rawCodexCompat.fingerprintDedup !== false
304
349
  };
350
+ if (cfg.procedural !== void 0 && (cfg.procedural === null || typeof cfg.procedural !== "object" || Array.isArray(cfg.procedural))) {
351
+ throw new Error(
352
+ `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).`
353
+ );
354
+ }
305
355
  const rawProcedural = cfg.procedural && typeof cfg.procedural === "object" && !Array.isArray(cfg.procedural) ? cfg.procedural : {};
306
- const proceduralMinRaw = typeof rawProcedural.minOccurrences === "number" && Number.isFinite(rawProcedural.minOccurrences) ? Math.floor(rawProcedural.minOccurrences) : 3;
356
+ const proceduralMinCoerced = coerceNumber(rawProcedural.minOccurrences);
357
+ const proceduralMinRaw = proceduralMinCoerced !== void 0 ? Math.floor(proceduralMinCoerced) : 3;
358
+ const successFloorRaw = coerceNumber(rawProcedural.successFloor);
359
+ const successFloor = successFloorRaw !== void 0 && successFloorRaw >= 0 && successFloorRaw <= 1 ? successFloorRaw : 0.75;
360
+ const autoPromoteOccRaw = coerceNumber(rawProcedural.autoPromoteOccurrences);
361
+ const autoPromoteOccurrences = autoPromoteOccRaw !== void 0 && Number.isFinite(autoPromoteOccRaw) ? autoPromoteOccRaw <= 0 ? 0 : Math.min(1e4, Math.max(1, Math.floor(autoPromoteOccRaw))) : 8;
362
+ const lookbackCoerced = coerceNumber(rawProcedural.lookbackDays);
363
+ const lookbackDays = lookbackCoerced !== void 0 && Number.isFinite(lookbackCoerced) ? Math.min(3650, Math.max(1, Math.floor(lookbackCoerced))) : 14;
364
+ const recallMaxCoerced = coerceNumber(rawProcedural.recallMaxProcedures);
365
+ const recallMaxProcedures = recallMaxCoerced !== void 0 && Number.isFinite(recallMaxCoerced) ? Math.min(10, Math.max(1, Math.floor(recallMaxCoerced))) : 2;
366
+ const rawEnabledValue = rawProcedural.enabled;
367
+ let proceduralEnabled;
368
+ if (rawEnabledValue === void 0) {
369
+ proceduralEnabled = true;
370
+ } else {
371
+ const enabledCoerced = coerceBool(rawEnabledValue);
372
+ if (enabledCoerced === void 0) {
373
+ throw new Error(
374
+ `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).`
375
+ );
376
+ }
377
+ proceduralEnabled = enabledCoerced;
378
+ }
307
379
  const procedural = {
308
- enabled: coerceBool(rawProcedural.enabled) === true,
309
- /** 0 disables miner emission threshold (no clusters qualify). */
380
+ enabled: proceduralEnabled,
381
+ /** `0` skips all mining (`minOccurrences_zero`); otherwise clusters need at least this many members. */
310
382
  minOccurrences: Math.min(1e3, Math.max(0, proceduralMinRaw)),
311
- successFloor: typeof rawProcedural.successFloor === "number" && Number.isFinite(rawProcedural.successFloor) && rawProcedural.successFloor >= 0 && rawProcedural.successFloor <= 1 ? rawProcedural.successFloor : 0.7,
312
- autoPromoteOccurrences: typeof rawProcedural.autoPromoteOccurrences === "number" && Number.isFinite(rawProcedural.autoPromoteOccurrences) ? rawProcedural.autoPromoteOccurrences <= 0 ? 0 : Math.min(1e4, Math.max(1, Math.floor(rawProcedural.autoPromoteOccurrences))) : 8,
383
+ successFloor,
384
+ autoPromoteOccurrences,
313
385
  autoPromoteEnabled: coerceBool(rawProcedural.autoPromoteEnabled) === true,
314
- lookbackDays: typeof rawProcedural.lookbackDays === "number" && Number.isFinite(rawProcedural.lookbackDays) ? Math.min(3650, Math.max(1, Math.floor(rawProcedural.lookbackDays))) : 30,
386
+ lookbackDays,
315
387
  proceduralMiningCronAutoRegister: coerceBool(rawProcedural.proceduralMiningCronAutoRegister) === true,
316
- recallMaxProcedures: typeof rawProcedural.recallMaxProcedures === "number" && Number.isFinite(rawProcedural.recallMaxProcedures) ? Math.min(10, Math.max(1, Math.floor(rawProcedural.recallMaxProcedures))) : 3
388
+ recallMaxProcedures
389
+ };
390
+ const rawCodingMode = cfg.codingMode && typeof cfg.codingMode === "object" && !Array.isArray(cfg.codingMode) ? cfg.codingMode : {};
391
+ const codingProjectScopeRaw = coerceBool(rawCodingMode.projectScope);
392
+ const codingBranchScopeRaw = coerceBool(rawCodingMode.branchScope);
393
+ const codingMode = {
394
+ projectScope: codingProjectScopeRaw === void 0 ? true : codingProjectScopeRaw,
395
+ branchScope: codingBranchScopeRaw === true
317
396
  };
318
397
  const memoryDir = typeof cfg.memoryDir === "string" && cfg.memoryDir.length > 0 ? cfg.memoryDir : DEFAULT_MEMORY_DIR;
319
398
  const rawIdentityInjectionMode = cfg.identityInjectionMode;
@@ -422,6 +501,36 @@ function parseConfig(raw) {
422
501
  triggerMode,
423
502
  bufferMaxTurns: typeof cfg.bufferMaxTurns === "number" ? cfg.bufferMaxTurns : 5,
424
503
  bufferMaxMinutes: typeof cfg.bufferMaxMinutes === "number" ? cfg.bufferMaxMinutes : 15,
504
+ // Surprise-gated buffer flush (issue #563, D-MEM). See types.ts for
505
+ // semantics. Default off so PR 2 ships as a pure no-op until an operator
506
+ // opts in. PR 4 benchmarks the flag and may flip the default.
507
+ //
508
+ // Use `coerceBool` rather than a strict `=== true` check: CLI operators
509
+ // set booleans via `--config bufferSurpriseTriggerEnabled=true` which
510
+ // arrives as the string `"true"` — the strict form would silently
511
+ // leave the flag off. Matches the coercion contract established for
512
+ // other boolean config keys (CLAUDE.md rule #36).
513
+ bufferSurpriseTriggerEnabled: coerceBool(cfg.bufferSurpriseTriggerEnabled) === true,
514
+ // Numeric surprise knobs go through `coerceNumber` so CLI operators
515
+ // can pass `--config bufferSurpriseThreshold=0.5` without the string
516
+ // silently dropping to the default. Matches the coercion contract
517
+ // applied to other numeric config keys (CLAUDE.md rule #28).
518
+ bufferSurpriseThreshold: clampSurpriseThreshold(
519
+ coerceNumber(cfg.bufferSurpriseThreshold),
520
+ 0.35
521
+ ),
522
+ bufferSurpriseK: clampSurpriseK(
523
+ coerceNumber(cfg.bufferSurpriseK),
524
+ 5
525
+ ),
526
+ bufferSurpriseRecentMemoryCount: clampSurpriseRecentMemoryCount(
527
+ coerceNumber(cfg.bufferSurpriseRecentMemoryCount),
528
+ 20
529
+ ),
530
+ bufferSurpriseProbeTimeoutMs: clampSurpriseProbeTimeoutMs(
531
+ coerceNumber(cfg.bufferSurpriseProbeTimeoutMs),
532
+ 2e3
533
+ ),
425
534
  consolidateEveryN: typeof cfg.consolidateEveryN === "number" ? cfg.consolidateEveryN : 3,
426
535
  highSignalPatterns: Array.isArray(cfg.highSignalPatterns) ? cfg.highSignalPatterns : [],
427
536
  maxMemoryTokens: typeof cfg.maxMemoryTokens === "number" ? cfg.maxMemoryTokens : 2e3,
@@ -497,13 +606,62 @@ function parseConfig(raw) {
497
606
  contradictionSimilarityThreshold: typeof cfg.contradictionSimilarityThreshold === "number" ? cfg.contradictionSimilarityThreshold : 0.7,
498
607
  contradictionMinConfidence: typeof cfg.contradictionMinConfidence === "number" ? cfg.contradictionMinConfidence : 0.9,
499
608
  contradictionAutoResolve: cfg.contradictionAutoResolve !== false,
609
+ // Contradiction Scan cron (issue #520)
610
+ contradictionScan: parseContradictionScanConfig(cfg.contradictionScan),
500
611
  // Temporal Supersession (issue #375)
501
612
  temporalSupersessionEnabled: cfg.temporalSupersessionEnabled !== false,
502
613
  // On by default
503
614
  temporalSupersessionIncludeInRecall: cfg.temporalSupersessionIncludeInRecall === true,
504
615
  // Off by default
505
- // Direct-answer retrieval tier (issue #518)
506
- recallDirectAnswerEnabled: coerceBool(cfg.recallDirectAnswerEnabled) ?? false,
616
+ // Direct-answer retrieval tier (issue #518). Default on — the
617
+ // tier runs in observation mode: it annotates
618
+ // LastRecallSnapshot.tierExplain but never short-circuits the
619
+ // QMD path. Operators can opt out with
620
+ // recallDirectAnswerEnabled=false.
621
+ recallDirectAnswerEnabled: coerceBool(cfg.recallDirectAnswerEnabled) ?? true,
622
+ // Graph-based retrieval tier (issue #559 PR 4). Default `false` —
623
+ // the tier ships off pending the `retrieval-graph` bench in PR 5.
624
+ recallGraphEnabled: coerceBool(cfg.recallGraphEnabled) ?? false,
625
+ recallGraphDamping: (() => {
626
+ const n = coerceNumber(cfg.recallGraphDamping);
627
+ return n !== void 0 && n >= 0 && n < 1 ? n : 0.85;
628
+ })(),
629
+ // Fractional integer values (e.g. `0.5`) are REJECTED rather than
630
+ // silently floored to zero — CLAUDE.md rule 51 ("Reject invalid
631
+ // user input instead of silently defaulting"). Users who set a
632
+ // fractional iteration cap almost certainly meant an integer and
633
+ // quietly flooring their value to 0 turns off the tier without
634
+ // warning.
635
+ recallGraphIterations: (() => {
636
+ if (cfg.recallGraphIterations === void 0) return 20;
637
+ const n = coerceNumber(cfg.recallGraphIterations);
638
+ if (n === void 0 || !Number.isFinite(n) || n < 0 || n > 500) {
639
+ throw new Error(
640
+ `recallGraphIterations must be an integer in [0, 500] (got ${JSON.stringify(cfg.recallGraphIterations)}).`
641
+ );
642
+ }
643
+ if (!Number.isInteger(n)) {
644
+ throw new Error(
645
+ `recallGraphIterations must be an integer (got fractional value ${n}).`
646
+ );
647
+ }
648
+ return n;
649
+ })(),
650
+ recallGraphTopK: (() => {
651
+ if (cfg.recallGraphTopK === void 0) return 50;
652
+ const n = coerceNumber(cfg.recallGraphTopK);
653
+ if (n === void 0 || !Number.isFinite(n) || n < 0 || n > 1e4) {
654
+ throw new Error(
655
+ `recallGraphTopK must be an integer in [0, 10000] (got ${JSON.stringify(cfg.recallGraphTopK)}).`
656
+ );
657
+ }
658
+ if (!Number.isInteger(n)) {
659
+ throw new Error(
660
+ `recallGraphTopK must be an integer (got fractional value ${n}).`
661
+ );
662
+ }
663
+ return n;
664
+ })(),
507
665
  recallDirectAnswerTokenOverlapFloor: (() => {
508
666
  const n = coerceNumber(cfg.recallDirectAnswerTokenOverlapFloor);
509
667
  return n !== void 0 && n >= 0 && n <= 1 ? n : 0.55;
@@ -521,6 +679,71 @@ function parseConfig(raw) {
521
679
  ) ? cfg.recallDirectAnswerEligibleTaxonomyBuckets.filter(
522
680
  (v) => typeof v === "string" && v.length > 0
523
681
  ) : ["decisions", "principles", "conventions", "runbooks", "entities"],
682
+ // Cross-namespace query-budget limiter (issue #565 PR 4/5).
683
+ // Defaults to false — ships disabled so existing deployments are
684
+ // unaffected. When enabled, the read path throttles a principal that
685
+ // issues a burst of recalls against namespaces other than their own.
686
+ recallCrossNamespaceBudgetEnabled: coerceBool(cfg.recallCrossNamespaceBudgetEnabled) ?? false,
687
+ recallCrossNamespaceBudgetWindowMs: (() => {
688
+ const n = coerceNumber(cfg.recallCrossNamespaceBudgetWindowMs);
689
+ return n !== void 0 && n > 0 ? Math.floor(n) : 6e4;
690
+ })(),
691
+ recallCrossNamespaceBudgetSoftLimit: (() => {
692
+ const n = coerceNumber(cfg.recallCrossNamespaceBudgetSoftLimit);
693
+ return n !== void 0 && n >= 0 ? Math.floor(n) : 10;
694
+ })(),
695
+ recallCrossNamespaceBudgetHardLimit: (() => {
696
+ const n = coerceNumber(cfg.recallCrossNamespaceBudgetHardLimit);
697
+ return n !== void 0 && n > 0 ? Math.floor(n) : 30;
698
+ })(),
699
+ // Recall-audit anomaly detector (issue #565 PR 5/5). Defaults off so
700
+ // existing deployments are unaffected; enable explicitly to let the
701
+ // access surfaces flag suspicious query patterns derived from the
702
+ // audit trail. Thresholds floor AFTER validating the floored value
703
+ // is still >= 1 — a `0.5` input that floors to 0 would turn every
704
+ // detector into a flood-on-anything, flipping the default to
705
+ // max-noise instead of max-silence.
706
+ recallAuditAnomalyDetectionEnabled: coerceBool(cfg.recallAuditAnomalyDetectionEnabled) ?? false,
707
+ recallAuditAnomalyWindowMs: (() => {
708
+ const n = coerceNumber(cfg.recallAuditAnomalyWindowMs);
709
+ if (n === void 0) return 5 * 6e4;
710
+ const floored = Math.floor(n);
711
+ return floored >= 1 ? floored : 5 * 6e4;
712
+ })(),
713
+ recallAuditAnomalyRepeatQueryLimit: (() => {
714
+ const n = coerceNumber(cfg.recallAuditAnomalyRepeatQueryLimit);
715
+ if (n === void 0) return 5;
716
+ const floored = Math.floor(n);
717
+ return floored >= 1 ? floored : 5;
718
+ })(),
719
+ recallAuditAnomalyNamespaceWalkLimit: (() => {
720
+ const n = coerceNumber(cfg.recallAuditAnomalyNamespaceWalkLimit);
721
+ if (n === void 0) return 3;
722
+ const floored = Math.floor(n);
723
+ return floored >= 1 ? floored : 3;
724
+ })(),
725
+ recallAuditAnomalyHighCardinalityLimit: (() => {
726
+ const n = coerceNumber(cfg.recallAuditAnomalyHighCardinalityLimit);
727
+ if (n === void 0) return 50;
728
+ const floored = Math.floor(n);
729
+ return floored >= 1 ? floored : 50;
730
+ })(),
731
+ recallAuditAnomalyRapidFireLimit: (() => {
732
+ const n = coerceNumber(cfg.recallAuditAnomalyRapidFireLimit);
733
+ if (n === void 0) return 30;
734
+ const floored = Math.floor(n);
735
+ return floored >= 1 ? floored : 30;
736
+ })(),
737
+ // Memory Worth recall filter (issue #560 PR 4, default flipped in PR 5).
738
+ // Bench result on the seeded fixture: precision@5 lifts from 0.00 to
739
+ // 0.60 across all 50 cases with zero regressions. See
740
+ // `runMemoryWorthBench` in memory-worth-bench.ts. Operators can still
741
+ // opt out with recallMemoryWorthFilterEnabled=false.
742
+ recallMemoryWorthFilterEnabled: coerceBool(cfg.recallMemoryWorthFilterEnabled) ?? true,
743
+ recallMemoryWorthHalfLifeMs: (() => {
744
+ const n = coerceNumber(cfg.recallMemoryWorthHalfLifeMs);
745
+ return n !== void 0 && n >= 0 ? n : 0;
746
+ })(),
524
747
  // Memory Linking (Phase 3A)
525
748
  memoryLinkingEnabled: cfg.memoryLinkingEnabled === true,
526
749
  // Off by default initially
@@ -597,6 +820,7 @@ function parseConfig(raw) {
597
820
  activeRecallAllowChainedActiveMemory: cfg.activeRecallAllowChainedActiveMemory === true,
598
821
  dreaming,
599
822
  procedural,
823
+ codingMode,
600
824
  heartbeat,
601
825
  slotBehavior,
602
826
  codexCompat,
@@ -669,6 +893,17 @@ function parseConfig(raw) {
669
893
  ) : ["correction", "commitment", "procedure"],
670
894
  semanticConsolidationIntervalHours: typeof cfg.semanticConsolidationIntervalHours === "number" ? Math.max(1, Math.floor(cfg.semanticConsolidationIntervalHours)) : 168,
671
895
  semanticConsolidationMaxPerRun: typeof cfg.semanticConsolidationMaxPerRun === "number" ? Math.max(0, Math.floor(cfg.semanticConsolidationMaxPerRun)) : 100,
896
+ // Operator-aware consolidation prompt (issue #561 PR 3). Defaults
897
+ // to `false` to match sibling `*Enabled` flags' least-privileged
898
+ // convention. Operators opt in by setting `true` (or truthy
899
+ // coercions like "true", "1", "yes", "on") when they want the
900
+ // consolidation LLM to emit SPLIT/MERGE/UPDATE operator selection
901
+ // on the `derived_via` frontmatter field. Uses `coerceBool` per
902
+ // Gotcha #36 so CLI / env-string inputs coerce correctly. When
903
+ // disabled, `derived_via` is still populated via the cluster-shape
904
+ // heuristic (chooseConsolidationOperator) so PR 2's provenance
905
+ // wiring keeps working without operator-aware prompts.
906
+ operatorAwareConsolidationEnabled: coerceBool(cfg.operatorAwareConsolidationEnabled) ?? false,
672
907
  creationMemoryEnabled: cfg.creationMemoryEnabled === true,
673
908
  memoryUtilityLearningEnabled: cfg.memoryUtilityLearningEnabled === true,
674
909
  promotionByOutcomeEnabled: cfg.promotionByOutcomeEnabled === true,
@@ -742,6 +977,21 @@ function parseConfig(raw) {
742
977
  extractionJudgeModel: typeof cfg.extractionJudgeModel === "string" ? cfg.extractionJudgeModel : "",
743
978
  extractionJudgeBatchSize: typeof cfg.extractionJudgeBatchSize === "number" && Number.isFinite(cfg.extractionJudgeBatchSize) ? Math.max(1, Math.round(cfg.extractionJudgeBatchSize)) : 20,
744
979
  extractionJudgeShadow: cfg.extractionJudgeShadow === true,
980
+ // Defer cap (issue #562 PR 2): max re-deferrals for the same candidate
981
+ // text before the verdict is forcibly converted to reject.
982
+ extractionJudgeMaxDeferrals: typeof cfg.extractionJudgeMaxDeferrals === "number" && Number.isFinite(cfg.extractionJudgeMaxDeferrals) && cfg.extractionJudgeMaxDeferrals >= 1 ? Math.floor(cfg.extractionJudgeMaxDeferrals) : 2,
983
+ // Judge telemetry (issue #562 PR 3): opt-in structured emit to the
984
+ // observation ledger for defer-rate / latency metrics.
985
+ // Uses `coerceBool` so CLI-style string inputs (`"true"`, `"false"`,
986
+ // `"1"`, `"0"`) are accepted consistently with the rest of the
987
+ // codebase (CLAUDE.md gotcha 36).
988
+ extractionJudgeTelemetryEnabled: coerceBool(cfg.extractionJudgeTelemetryEnabled) === true,
989
+ // Judge training-pair collection (issue #562 PR 4): opt-in shim for a
990
+ // future GRPO training pipeline. Rows land under ~/.remnic/judge-
991
+ // training/<date>.jsonl — NOT in the shared memory directory.
992
+ // Uses `coerceBool` per CLAUDE.md gotcha 36 for CLI-string parity.
993
+ collectJudgeTrainingPairs: coerceBool(cfg.collectJudgeTrainingPairs) === true,
994
+ judgeTrainingDir: typeof cfg.judgeTrainingDir === "string" ? cfg.judgeTrainingDir : "",
745
995
  // Inline source attribution (issue #369). Opt-in to preserve
746
996
  // backwards compatibility with existing downstream consumers.
747
997
  inlineSourceAttributionEnabled: cfg.inlineSourceAttributionEnabled === true,
@@ -765,6 +1015,22 @@ function parseConfig(raw) {
765
1015
  localLlmFastModel: typeof cfg.localLlmFastModel === "string" && cfg.localLlmFastModel.length > 0 ? cfg.localLlmFastModel : "",
766
1016
  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",
767
1017
  localLlmFastTimeoutMs: typeof cfg.localLlmFastTimeoutMs === "number" ? cfg.localLlmFastTimeoutMs : 15e3,
1018
+ // Thinking-mode suppression on the main local LLM (issue #548).
1019
+ // Default true — extraction / consolidation produce structured
1020
+ // JSON and gain nothing from chain-of-thought; thinking-capable
1021
+ // models burn their token budget on reasoning and blow the
1022
+ // default 60s timeout. Operators who need thinking on the main
1023
+ // client (e.g. for narrative tasks) can set this to false via
1024
+ // config or --config CLI flag. The fast-tier `fastLlm` always
1025
+ // disables thinking and is unaffected by this flag.
1026
+ //
1027
+ // Injection is backend-gated inside LocalLlmClient: the
1028
+ // `chat_template_kwargs` field is only sent when the detected
1029
+ // backend is in `THINKING_COMPATIBLE_BACKENDS` (LM Studio, vLLM).
1030
+ // Strict OpenAI-compatible backends reject unknown request
1031
+ // fields with 400, so the client fails open on unknown backends
1032
+ // rather than tripping the 400 cooldown (Codex P1 on PR #550).
1033
+ localLlmDisableThinking: coerceBool(cfg.localLlmDisableThinking) ?? true,
768
1034
  // Gateway config (passed from index.ts for fallback AI)
769
1035
  gatewayConfig: cfg.gatewayConfig,
770
1036
  // Gateway model source (v9.2) — route LLM calls through gateway agent model chain
@@ -857,6 +1123,8 @@ function parseConfig(raw) {
857
1123
  recallMmrEnabled: cfg.recallMmrEnabled !== false,
858
1124
  recallMmrLambda: typeof cfg.recallMmrLambda === "number" && Number.isFinite(cfg.recallMmrLambda) ? Math.min(1, Math.max(0, cfg.recallMmrLambda)) : 0.7,
859
1125
  recallMmrTopN: typeof cfg.recallMmrTopN === "number" && Number.isFinite(cfg.recallMmrTopN) ? Math.max(0, Math.floor(cfg.recallMmrTopN)) : 40,
1126
+ // Issue #564 PR 3: off by default; enable explicitly after bench validation.
1127
+ recallReasoningTraceBoostEnabled: coerceBool(cfg.recallReasoningTraceBoostEnabled) ?? false,
860
1128
  qmdRecallCacheTtlMs: typeof cfg.qmdRecallCacheTtlMs === "number" ? Math.max(0, Math.floor(cfg.qmdRecallCacheTtlMs)) : 6e4,
861
1129
  qmdRecallCacheStaleTtlMs: typeof cfg.qmdRecallCacheStaleTtlMs === "number" ? Math.max(0, Math.floor(cfg.qmdRecallCacheStaleTtlMs)) : 10 * 6e4,
862
1130
  qmdRecallCacheMaxEntries: typeof cfg.qmdRecallCacheMaxEntries === "number" ? Math.max(0, Math.floor(cfg.qmdRecallCacheMaxEntries)) : 128,
@@ -1140,6 +1408,22 @@ function clampNonNegativeNumber(value) {
1140
1408
  if (typeof value !== "number" || !Number.isFinite(value)) return void 0;
1141
1409
  return Math.max(0, Math.floor(value));
1142
1410
  }
1411
+ function clampSurpriseThreshold(value, fallback) {
1412
+ if (value === void 0) return fallback;
1413
+ return Math.min(1, Math.max(0, value));
1414
+ }
1415
+ function clampSurpriseK(value, fallback) {
1416
+ if (value === void 0) return fallback;
1417
+ return Math.max(1, Math.floor(value));
1418
+ }
1419
+ function clampSurpriseRecentMemoryCount(value, fallback) {
1420
+ if (value === void 0) return fallback;
1421
+ return Math.max(0, Math.floor(value));
1422
+ }
1423
+ function clampSurpriseProbeTimeoutMs(value, fallback) {
1424
+ if (value === void 0) return fallback;
1425
+ return Math.max(1, Math.floor(value));
1426
+ }
1143
1427
  function parseRecallSectionEntry(raw) {
1144
1428
  const entry = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
1145
1429
  return {
@@ -1199,7 +1483,24 @@ function buildDefaultRecallPipeline(cfg) {
1199
1483
  { id: "verbatim-artifacts", enabled: cfg.verbatimArtifactsEnabled === true },
1200
1484
  {
1201
1485
  id: "procedure-recall",
1202
- enabled: typeof cfg.procedural === "object" && cfg.procedural !== null && !Array.isArray(cfg.procedural) && cfg.procedural.enabled === true,
1486
+ // Default-on since issue #567 PR 4/5: the master `procedural.enabled`
1487
+ // gate now defaults to `true` when the key is omitted, so the recall
1488
+ // pipeline must stay in sync. Explicit `false` (or any coerceBool
1489
+ // falsy variant) still disables recall injection.
1490
+ //
1491
+ // CLAUDE.md rule 48 (least-privileged defaults) + Cursor review on #609:
1492
+ // never fail open on unrecognized values. Only `coerced === true` or
1493
+ // the "key omitted" path enables the section. `parseConfig` throws
1494
+ // on invalid values upstream, so this branch only ever sees boolean
1495
+ // results — `coerced === undefined` should never happen in practice,
1496
+ // but defense-in-depth keeps the section disabled if it ever does.
1497
+ enabled: (() => {
1498
+ const proceduralRaw = typeof cfg.procedural === "object" && cfg.procedural !== null && !Array.isArray(cfg.procedural) ? cfg.procedural : void 0;
1499
+ if (proceduralRaw === void 0) return true;
1500
+ const rawEnabled = proceduralRaw.enabled;
1501
+ if (rawEnabled === void 0) return true;
1502
+ return coerceBool(rawEnabled) === true;
1503
+ })(),
1203
1504
  maxChars: 2400
1204
1505
  },
1205
1506
  { id: "memory-boxes", enabled: cfg.memoryBoxesEnabled === true },
@@ -1305,4 +1606,4 @@ export {
1305
1606
  VALID_MEMORY_CATEGORIES,
1306
1607
  parseConfig
1307
1608
  };
1308
- //# sourceMappingURL=chunk-OJFGVJS6.js.map
1609
+ //# sourceMappingURL=chunk-BK2EFTE2.js.map