@remnic/core 1.1.2 → 1.1.4

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 (489) hide show
  1. package/dist/abort-error.js +1 -0
  2. package/dist/abstraction-nodes.js +1 -0
  3. package/dist/access-audit.js +1 -0
  4. package/dist/access-cli.js +72 -47
  5. package/dist/access-cli.js.map +1 -1
  6. package/dist/access-http.d.ts +50 -5
  7. package/dist/access-http.js +39 -16
  8. package/dist/access-idempotency.js +1 -0
  9. package/dist/access-mcp.d.ts +10 -5
  10. package/dist/access-mcp.js +38 -14
  11. package/dist/access-schema.d.ts +133 -13
  12. package/dist/access-schema.js +20 -1
  13. package/dist/access-service-CtXFnprR.d.ts +2033 -0
  14. package/dist/access-service.d.ts +11 -6
  15. package/dist/access-service.js +40 -15
  16. package/dist/active-memory-bridge.js +1 -0
  17. package/dist/active-recall.js +1 -0
  18. package/dist/active-recall.js.map +1 -1
  19. package/dist/behavior-learner.js +1 -0
  20. package/dist/behavior-learner.js.map +1 -1
  21. package/dist/behavior-signals.js +1 -0
  22. package/dist/bootstrap.d.ts +6 -4
  23. package/dist/bootstrap.js +1 -0
  24. package/dist/boxes.js +1 -0
  25. package/dist/briefing.d.ts +9 -5
  26. package/dist/briefing.js +10 -7
  27. package/dist/buffer-surprise-report.js +1 -0
  28. package/dist/buffer-surprise.js +1 -0
  29. package/dist/buffer.d.ts +1 -1
  30. package/dist/buffer.js +1 -0
  31. package/dist/calibration.d.ts +8 -1
  32. package/dist/calibration.js +10 -2
  33. package/dist/calibration.js.map +1 -1
  34. package/dist/capsule-cli.d.ts +137 -0
  35. package/dist/capsule-cli.js +34 -0
  36. package/dist/capsule-crypto-5CYAGVC5.js +18 -0
  37. package/dist/capsule-export-NZQPOTQ4.js +17 -0
  38. package/dist/capsule-export-NZQPOTQ4.js.map +1 -0
  39. package/dist/capsule-import-SDCUXLEV.js +16 -0
  40. package/dist/capsule-import-SDCUXLEV.js.map +1 -0
  41. package/dist/capsule-merge-DI7PNQ2H.js +189 -0
  42. package/dist/capsule-merge-DI7PNQ2H.js.map +1 -0
  43. package/dist/causal-behavior.js +1 -0
  44. package/dist/causal-behavior.js.map +1 -1
  45. package/dist/causal-chain.js +1 -0
  46. package/dist/causal-consolidation.js +12 -9
  47. package/dist/causal-consolidation.js.map +1 -1
  48. package/dist/causal-retrieval.js +2 -1
  49. package/dist/causal-retrieval.js.map +1 -1
  50. package/dist/causal-trajectory-graph.js +4 -1
  51. package/dist/causal-trajectory-graph.js.map +1 -1
  52. package/dist/causal-trajectory.js +2 -1
  53. package/dist/chunk-2LSZVONP.js +67 -0
  54. package/dist/chunk-2LSZVONP.js.map +1 -0
  55. package/dist/chunk-32KD5IHZ.js +245 -0
  56. package/dist/chunk-32KD5IHZ.js.map +1 -0
  57. package/dist/chunk-3KIS4VGT.js +228 -0
  58. package/dist/chunk-3KIS4VGT.js.map +1 -0
  59. package/dist/chunk-3LCWFNVS.js +350 -0
  60. package/dist/chunk-3LCWFNVS.js.map +1 -0
  61. package/dist/chunk-43EKP2UK.js +26 -0
  62. package/dist/chunk-43EKP2UK.js.map +1 -0
  63. package/dist/chunk-457A4P3L.js +119 -0
  64. package/dist/chunk-457A4P3L.js.map +1 -0
  65. package/dist/{chunk-TMYO7B5P.js → chunk-47WOM4YW.js} +2 -2
  66. package/dist/{chunk-FVA6TGI3.js → chunk-52PDY6GD.js} +42 -2
  67. package/dist/chunk-52PDY6GD.js.map +1 -0
  68. package/dist/{chunk-ULYOGL6R.js → chunk-5HRY2WRF.js} +7 -3
  69. package/dist/chunk-5HRY2WRF.js.map +1 -0
  70. package/dist/{chunk-BOUYNNYD.js → chunk-67YLUWLG.js} +32 -13
  71. package/dist/{chunk-BOUYNNYD.js.map → chunk-67YLUWLG.js.map} +1 -1
  72. package/dist/chunk-6TBWYBJ3.js +236 -0
  73. package/dist/chunk-6TBWYBJ3.js.map +1 -0
  74. package/dist/chunk-74EMIVE4.js +329 -0
  75. package/dist/chunk-74EMIVE4.js.map +1 -0
  76. package/dist/chunk-74WWN7ZW.js +82 -0
  77. package/dist/chunk-74WWN7ZW.js.map +1 -0
  78. package/dist/chunk-A6XUJE5D.js +126 -0
  79. package/dist/chunk-A6XUJE5D.js.map +1 -0
  80. package/dist/{chunk-STGWEHYR.js → chunk-AEMBDV7M.js} +1187 -62
  81. package/dist/chunk-AEMBDV7M.js.map +1 -0
  82. package/dist/{chunk-PVICZTKG.js → chunk-AGZHRWPT.js} +5 -5
  83. package/dist/{chunk-PVICZTKG.js.map → chunk-AGZHRWPT.js.map} +1 -1
  84. package/dist/chunk-AJA46VX5.js +393 -0
  85. package/dist/chunk-AJA46VX5.js.map +1 -0
  86. package/dist/chunk-ASIQZXYO.js +277 -0
  87. package/dist/chunk-ASIQZXYO.js.map +1 -0
  88. package/dist/{chunk-DG6YMRDC.js → chunk-B2TL6GA2.js} +2 -2
  89. package/dist/chunk-BJMBJZ2Y.js +290 -0
  90. package/dist/chunk-BJMBJZ2Y.js.map +1 -0
  91. package/dist/chunk-BT7NVCML.js +79 -0
  92. package/dist/chunk-BT7NVCML.js.map +1 -0
  93. package/dist/chunk-CK5NTM2S.js +454 -0
  94. package/dist/chunk-CK5NTM2S.js.map +1 -0
  95. package/dist/{chunk-AYXIPSZO.js → chunk-CRU27Q4J.js} +2 -2
  96. package/dist/{chunk-UWB5LMWY.js → chunk-CUI2STX6.js} +526 -24
  97. package/dist/chunk-CUI2STX6.js.map +1 -0
  98. package/dist/{chunk-CUPFXL3J.js → chunk-EGEPUGN4.js} +4 -4
  99. package/dist/chunk-EGEPUGN4.js.map +1 -0
  100. package/dist/{chunk-3OGMS3PE.js → chunk-F5VQOQ2E.js} +3 -2
  101. package/dist/chunk-F5VQOQ2E.js.map +1 -0
  102. package/dist/chunk-FP2373TW.js +149 -0
  103. package/dist/chunk-FP2373TW.js.map +1 -0
  104. package/dist/{chunk-RBBWYEFJ.js → chunk-G2WADRQ3.js} +1 -1
  105. package/dist/chunk-G7D6GZ5J.js +48 -0
  106. package/dist/chunk-G7D6GZ5J.js.map +1 -0
  107. package/dist/chunk-H7XKCNR6.js +60 -0
  108. package/dist/chunk-H7XKCNR6.js.map +1 -0
  109. package/dist/{chunk-LOIMBRDE.js → chunk-HIRKCQGF.js} +1994 -412
  110. package/dist/chunk-HIRKCQGF.js.map +1 -0
  111. package/dist/chunk-IXEJRKCZ.js +18 -0
  112. package/dist/chunk-IXEJRKCZ.js.map +1 -0
  113. package/dist/chunk-IYY4MCPG.js +275 -0
  114. package/dist/chunk-IYY4MCPG.js.map +1 -0
  115. package/dist/{chunk-BECYBZLX.js → chunk-JWSENLQI.js} +502 -22
  116. package/dist/chunk-JWSENLQI.js.map +1 -0
  117. package/dist/chunk-KNKUID7G.js +183 -0
  118. package/dist/chunk-KNKUID7G.js.map +1 -0
  119. package/dist/chunk-L2IO2QPY.js +2036 -0
  120. package/dist/chunk-L2IO2QPY.js.map +1 -0
  121. package/dist/{chunk-ZAIM4TUE.js → chunk-LW2NMHDW.js} +46 -1
  122. package/dist/chunk-LW2NMHDW.js.map +1 -0
  123. package/dist/chunk-MDYG7VI7.js +48 -0
  124. package/dist/chunk-MDYG7VI7.js.map +1 -0
  125. package/dist/{chunk-VDX363PS.js → chunk-MUELDH4F.js} +10 -3
  126. package/dist/chunk-MUELDH4F.js.map +1 -0
  127. package/dist/chunk-MXC3AP5I.js +74 -0
  128. package/dist/chunk-MXC3AP5I.js.map +1 -0
  129. package/dist/chunk-NN3TS5BM.js +147 -0
  130. package/dist/chunk-NN3TS5BM.js.map +1 -0
  131. package/dist/{chunk-3YGHKTBF.js → chunk-NZS2BLTP.js} +963 -326
  132. package/dist/chunk-NZS2BLTP.js.map +1 -0
  133. package/dist/chunk-OA3L7BFR.js +183 -0
  134. package/dist/chunk-OA3L7BFR.js.map +1 -0
  135. package/dist/chunk-OZHRDTDX.js +240 -0
  136. package/dist/chunk-OZHRDTDX.js.map +1 -0
  137. package/dist/chunk-PCUKNJAZ.js +165 -0
  138. package/dist/chunk-PCUKNJAZ.js.map +1 -0
  139. package/dist/{chunk-6PFRXT4K.js → chunk-PFV5C235.js} +11 -6
  140. package/dist/chunk-PFV5C235.js.map +1 -0
  141. package/dist/chunk-PZ5AY32C.js +10 -0
  142. package/dist/chunk-PZ5AY32C.js.map +1 -0
  143. package/dist/{chunk-Y7R2XJ5Q.js → chunk-Q7FJ5ZHM.js} +6 -2
  144. package/dist/chunk-Q7FJ5ZHM.js.map +1 -0
  145. package/dist/{chunk-WCLICCGB.js → chunk-RILIVK4O.js} +91 -4
  146. package/dist/chunk-RILIVK4O.js.map +1 -0
  147. package/dist/{chunk-C2EFFULQ.js → chunk-RK2Y4XOM.js} +163 -20
  148. package/dist/chunk-RK2Y4XOM.js.map +1 -0
  149. package/dist/{chunk-TP4FZJIZ.js → chunk-RULE4VG5.js} +5 -1
  150. package/dist/chunk-RULE4VG5.js.map +1 -0
  151. package/dist/{chunk-PVPWZSSI.js → chunk-SMA4IMHV.js} +19 -3
  152. package/dist/chunk-SMA4IMHV.js.map +1 -0
  153. package/dist/{chunk-6YJHX2DL.js → chunk-TIFRGAKO.js} +242 -22
  154. package/dist/chunk-TIFRGAKO.js.map +1 -0
  155. package/dist/chunk-TUFG6VXY.js +875 -0
  156. package/dist/chunk-TUFG6VXY.js.map +1 -0
  157. package/dist/chunk-TYEOAFH3.js +251 -0
  158. package/dist/chunk-TYEOAFH3.js.map +1 -0
  159. package/dist/chunk-UKJAGEXH.js +260 -0
  160. package/dist/chunk-UKJAGEXH.js.map +1 -0
  161. package/dist/{chunk-KVBLZUKV.js → chunk-USFPPRAF.js} +93 -3
  162. package/dist/chunk-USFPPRAF.js.map +1 -0
  163. package/dist/{chunk-NBVAS5MT.js → chunk-V7TEH5I2.js} +6 -6
  164. package/dist/{chunk-GA5P7RST.js → chunk-VTJVUHRK.js} +22 -36
  165. package/dist/chunk-VTJVUHRK.js.map +1 -0
  166. package/dist/{chunk-SPI27QT6.js → chunk-W7WWT4FJ.js} +9 -4
  167. package/dist/chunk-W7WWT4FJ.js.map +1 -0
  168. package/dist/chunk-WIICJPET.js +45 -0
  169. package/dist/chunk-WIICJPET.js.map +1 -0
  170. package/dist/{chunk-VBVG2M5G.js → chunk-WPGJYVUH.js} +6 -2
  171. package/dist/chunk-WPGJYVUH.js.map +1 -0
  172. package/dist/{chunk-4HQS2HPX.js → chunk-WSZIHQBK.js} +29 -9
  173. package/dist/{chunk-4HQS2HPX.js.map → chunk-WSZIHQBK.js.map} +1 -1
  174. package/dist/{chunk-NZLQTHS5.js → chunk-WW3QQF4H.js} +4 -1
  175. package/dist/chunk-WW3QQF4H.js.map +1 -0
  176. package/dist/{chunk-DIXB44VE.js → chunk-X6VBWOVZ.js} +28 -13
  177. package/dist/chunk-X6VBWOVZ.js.map +1 -0
  178. package/dist/{chunk-XXVWLXSG.js → chunk-XQ4EJLUD.js} +64 -92
  179. package/dist/chunk-XQ4EJLUD.js.map +1 -0
  180. package/dist/{chunk-OC5OXUQ4.js → chunk-XRCYKJ3V.js} +780 -17
  181. package/dist/chunk-XRCYKJ3V.js.map +1 -0
  182. package/dist/{chunk-F5VP6YCB.js → chunk-Y4A6M3B6.js} +573 -156
  183. package/dist/chunk-Y4A6M3B6.js.map +1 -0
  184. package/dist/chunk-YNJHCGDT.js +309 -0
  185. package/dist/chunk-YNJHCGDT.js.map +1 -0
  186. package/dist/{chunk-L7IXWRYE.js → chunk-ZIBOQULP.js} +22 -13
  187. package/dist/chunk-ZIBOQULP.js.map +1 -0
  188. package/dist/{chunk-W6SL7OFG.js → chunk-ZTSE2ZJ6.js} +12 -2
  189. package/dist/{chunk-W6SL7OFG.js.map → chunk-ZTSE2ZJ6.js.map} +1 -1
  190. package/dist/chunking.js +1 -0
  191. package/dist/cipher-GVE2GQ5H.js +28 -0
  192. package/dist/cipher-GVE2GQ5H.js.map +1 -0
  193. package/dist/citations.js +1 -0
  194. package/dist/{cli-BkeRaYfk.d.ts → cli-lMql2FCr.d.ts} +26 -7
  195. package/dist/cli.d.ts +11 -6
  196. package/dist/cli.js +69 -34
  197. package/dist/codex-thread-key.js +1 -0
  198. package/dist/commitment-ledger.js +1 -0
  199. package/dist/compression-optimizer.js +1 -0
  200. package/dist/config.d.ts +2 -1
  201. package/dist/config.js +4 -1
  202. package/dist/connectors-cli-DFGtY2DB.d.ts +257 -0
  203. package/dist/connectors-cli.d.ts +2 -0
  204. package/dist/connectors-cli.js +22 -0
  205. package/dist/connectors-cli.js.map +1 -0
  206. package/dist/consolidation-operator.d.ts +65 -5
  207. package/dist/consolidation-operator.js +6 -1
  208. package/dist/consolidation-provenance-check.d.ts +1 -1
  209. package/dist/consolidation-provenance-check.js +3 -2
  210. package/dist/consolidation-undo.d.ts +1 -1
  211. package/dist/consolidation-undo.js +1 -0
  212. package/dist/consolidation-undo.js.map +1 -1
  213. package/dist/{contradiction-review-WIUBAR52.js → contradiction-review-5LTTVDQV.js} +2 -1
  214. package/dist/contradiction-review-5LTTVDQV.js.map +1 -0
  215. package/dist/{contradiction-scan-E3GJTI4F.js → contradiction-scan-3Z6YW7YA.js} +2 -1
  216. package/dist/{contradiction-scan-E3GJTI4F.js.map → contradiction-scan-3Z6YW7YA.js.map} +1 -1
  217. package/dist/cross-namespace-budget.js +1 -0
  218. package/dist/cue-anchors.js +1 -0
  219. package/dist/dashboard-runtime.js +1 -0
  220. package/dist/day-summary.js +1 -0
  221. package/dist/delinearize.js +1 -0
  222. package/dist/direct-answer-wiring.js +1 -0
  223. package/dist/direct-answer.js +1 -0
  224. package/dist/dreams-ledger-LR2NBAZE.js +286 -0
  225. package/dist/dreams-ledger-LR2NBAZE.js.map +1 -0
  226. package/dist/embedding-fallback.js +1 -0
  227. package/dist/engine-O6YWKQM3.js +28 -0
  228. package/dist/engine-O6YWKQM3.js.map +1 -0
  229. package/dist/entity-retrieval.d.ts +1 -1
  230. package/dist/entity-retrieval.js +10 -7
  231. package/dist/entity-schema.js +1 -0
  232. package/dist/evals.js +1 -0
  233. package/dist/evidence-pack.d.ts +16 -0
  234. package/dist/evidence-pack.js +8 -0
  235. package/dist/evidence-pack.js.map +1 -0
  236. package/dist/explicit-capture.d.ts +6 -4
  237. package/dist/explicit-capture.js +1 -0
  238. package/dist/extraction-judge-telemetry.js +1 -0
  239. package/dist/extraction-judge-training.js +1 -0
  240. package/dist/extraction-judge.js +1 -0
  241. package/dist/extraction.js +8 -7
  242. package/dist/fallback-llm.js +3 -2
  243. package/dist/first-start-migration-4MHQEOSD.js +263 -0
  244. package/dist/first-start-migration-4MHQEOSD.js.map +1 -0
  245. package/dist/forget-PLR6J5DN.js +69 -0
  246. package/dist/forget-PLR6J5DN.js.map +1 -0
  247. package/dist/framework-CyHYDcri.d.ts +153 -0
  248. package/dist/fs-utils-IRVUFB6G.js +30 -0
  249. package/dist/fs-utils-IRVUFB6G.js.map +1 -0
  250. package/dist/graph-dashboard-diff.js +1 -0
  251. package/dist/graph-dashboard-key.js +1 -0
  252. package/dist/graph-dashboard-parser.js +1 -0
  253. package/dist/graph-edge-decay-PWB63GRE.js +207 -0
  254. package/dist/graph-edge-decay-PWB63GRE.js.map +1 -0
  255. package/dist/graph-edge-reinforcement.d.ts +81 -0
  256. package/dist/graph-edge-reinforcement.js +24 -0
  257. package/dist/graph-edge-reinforcement.js.map +1 -0
  258. package/dist/graph-events.d.ts +87 -0
  259. package/dist/graph-events.js +14 -0
  260. package/dist/graph-events.js.map +1 -0
  261. package/dist/graph-recall.js +1 -0
  262. package/dist/graph-retrieval.js +1 -0
  263. package/dist/graph-snapshot.d.ts +112 -0
  264. package/dist/graph-snapshot.js +19 -0
  265. package/dist/graph-snapshot.js.map +1 -0
  266. package/dist/graph.d.ts +105 -7
  267. package/dist/graph.js +20 -3
  268. package/dist/harmonic-retrieval.js +1 -0
  269. package/dist/himem.js +1 -0
  270. package/dist/hygiene.js +1 -0
  271. package/dist/identity-continuity.js +1 -0
  272. package/dist/importance.js +1 -0
  273. package/dist/index.d.ts +574 -13
  274. package/dist/index.js +337 -69
  275. package/dist/index.js.map +1 -1
  276. package/dist/intent.js +1 -0
  277. package/dist/json-extract.js +1 -0
  278. package/dist/json-store.js +1 -0
  279. package/dist/kdf-7S6RWKLZ.js +26 -0
  280. package/dist/kdf-7S6RWKLZ.js.map +1 -0
  281. package/dist/legacy-hook-compat.js +1 -0
  282. package/dist/legacy-hook-compat.js.map +1 -1
  283. package/dist/lifecycle.js +1 -0
  284. package/dist/live-connectors-runner.d.ts +48 -0
  285. package/dist/live-connectors-runner.js +17 -0
  286. package/dist/live-connectors-runner.js.map +1 -0
  287. package/dist/local-llm.js +1 -0
  288. package/dist/logger.js +1 -0
  289. package/dist/memory-action-policy.js +1 -0
  290. package/dist/memory-cache.d.ts +2 -1
  291. package/dist/memory-cache.js +4 -1
  292. package/dist/memory-governance-JZHZDOLN.js +37 -0
  293. package/dist/memory-governance-JZHZDOLN.js.map +1 -0
  294. package/dist/memory-lifecycle-ledger-utils.d.ts +2 -1
  295. package/dist/memory-lifecycle-ledger-utils.js +4 -1
  296. package/dist/memory-projection-format.js +1 -0
  297. package/dist/{memory-projection-store-DeSXPh1j.d.ts → memory-projection-store-CY8TU40w.d.ts} +2 -1
  298. package/dist/memory-projection-store.d.ts +1 -1
  299. package/dist/memory-projection-store.js +2 -1
  300. package/dist/memory-worth-bench.js +1 -0
  301. package/dist/memory-worth-bench.js.map +1 -1
  302. package/dist/memory-worth-filter.js +1 -0
  303. package/dist/memory-worth-outcomes.d.ts +1 -1
  304. package/dist/memory-worth-outcomes.js +1 -0
  305. package/dist/memory-worth.js +1 -0
  306. package/dist/metadata-FC3XPDRQ.js +21 -0
  307. package/dist/metadata-FC3XPDRQ.js.map +1 -0
  308. package/dist/migrate-from-identity-anchor-TTEDEJGX.js +8 -0
  309. package/dist/migrate-from-identity-anchor-TTEDEJGX.js.map +1 -0
  310. package/dist/model-registry.js +1 -0
  311. package/dist/models-json.js +1 -0
  312. package/dist/native-knowledge.js +1 -0
  313. package/dist/negative.js +1 -0
  314. package/dist/objective-state-writers.js +1 -0
  315. package/dist/objective-state-writers.js.map +1 -1
  316. package/dist/objective-state.js +1 -0
  317. package/dist/openai-chat-compat.js +1 -0
  318. package/dist/operator-toolkit.d.ts +46 -2
  319. package/dist/operator-toolkit.js +29 -17
  320. package/dist/opik-exporter.js +1 -0
  321. package/dist/opik-exporter.js.map +1 -1
  322. package/dist/{orchestrator-CmJ-NTdJ.d.ts → orchestrator-ChkesB8U.d.ts} +177 -13
  323. package/dist/orchestrator.d.ts +6 -4
  324. package/dist/orchestrator.js +57 -41
  325. package/dist/page-versioning.js +1 -0
  326. package/dist/path-RMTY5Y5A.js +9 -0
  327. package/dist/path-RMTY5Y5A.js.map +1 -0
  328. package/dist/patterns-cli.d.ts +160 -0
  329. package/dist/patterns-cli.js +29 -0
  330. package/dist/patterns-cli.js.map +1 -0
  331. package/dist/peers-6OSQ3NK6.js +44 -0
  332. package/dist/peers-6OSQ3NK6.js.map +1 -0
  333. package/dist/plugin-id.js +1 -0
  334. package/dist/policy-runtime.js +1 -0
  335. package/dist/{port-BADbLZU5.d.ts → port-hqGnoStS.d.ts} +6 -0
  336. package/dist/profiling.js +1 -0
  337. package/dist/purge-6ATBGT77.js +205 -0
  338. package/dist/purge-6ATBGT77.js.map +1 -0
  339. package/dist/qmd-recall-cache.d.ts +1 -1
  340. package/dist/qmd-recall-cache.js +1 -0
  341. package/dist/qmd.d.ts +2 -1
  342. package/dist/qmd.js +4 -3
  343. package/dist/reasoning-trace-recall.js +1 -0
  344. package/dist/reasoning-trace-types.js +1 -0
  345. package/dist/recall-audit-anomaly.js +1 -0
  346. package/dist/recall-audit.js +1 -0
  347. package/dist/recall-disclosure-escalation.d.ts +84 -0
  348. package/dist/recall-disclosure-escalation.js +14 -0
  349. package/dist/recall-disclosure-escalation.js.map +1 -0
  350. package/dist/recall-explain-renderer.js +4 -1
  351. package/dist/recall-mmr.js +1 -0
  352. package/dist/recall-qos.js +1 -0
  353. package/dist/recall-query-policy.js +1 -0
  354. package/dist/recall-state.d.ts +7 -0
  355. package/dist/recall-state.js +2 -1
  356. package/dist/recall-tag-filter.d.ts +56 -0
  357. package/dist/recall-tag-filter.js +14 -0
  358. package/dist/recall-tag-filter.js.map +1 -0
  359. package/dist/recall-tokenization.js +1 -0
  360. package/dist/recall-xray-cli.d.ts +9 -2
  361. package/dist/recall-xray-cli.js +9 -4
  362. package/dist/recall-xray-renderer.js +4 -1
  363. package/dist/recall-xray.d.ts +116 -2
  364. package/dist/recall-xray.js +9 -3
  365. package/dist/reconstruct.js +1 -0
  366. package/dist/release-changelog.js +2 -0
  367. package/dist/release-changelog.js.map +1 -1
  368. package/dist/relevance.js +1 -0
  369. package/dist/rerank.js +1 -0
  370. package/dist/{resolution-QBTDHTG7.js → resolution-YGIBORXI.js} +2 -1
  371. package/dist/{resolution-QBTDHTG7.js.map → resolution-YGIBORXI.js.map} +1 -1
  372. package/dist/resolve-auth-token.d.ts +51 -0
  373. package/dist/resolve-auth-token.js +12 -0
  374. package/dist/resolve-auth-token.js.map +1 -0
  375. package/dist/resolve-provider-secret.d.ts +9 -1
  376. package/dist/resolve-provider-secret.js +4 -1
  377. package/dist/resume-bundles.js +4 -3
  378. package/dist/retrieval-agents.d.ts +1 -1
  379. package/dist/retrieval-agents.js +1 -0
  380. package/dist/retrieval-tiers.js +1 -0
  381. package/dist/retrieval.js +1 -0
  382. package/dist/sanitize.js +1 -0
  383. package/dist/schemas.d.ts +15 -2
  384. package/dist/schemas.js +2 -1
  385. package/dist/sdk-compat.js +1 -0
  386. package/dist/sdk-compat.js.map +1 -1
  387. package/dist/secure-store-4R2GSO7S.js +156 -0
  388. package/dist/secure-store-4R2GSO7S.js.map +1 -0
  389. package/dist/semantic-chunking.js +1 -0
  390. package/dist/{semantic-consolidation-CxJU6MJk.d.ts → semantic-consolidation-ByBXb-sf.d.ts} +3 -3
  391. package/dist/semantic-consolidation.d.ts +2 -2
  392. package/dist/semantic-consolidation.js +12 -7
  393. package/dist/semantic-rule-promotion.d.ts +1 -1
  394. package/dist/semantic-rule-promotion.js +10 -7
  395. package/dist/semantic-rule-verifier.d.ts +1 -1
  396. package/dist/semantic-rule-verifier.js +10 -7
  397. package/dist/session-integrity.js +1 -0
  398. package/dist/session-observer-bands.js +1 -0
  399. package/dist/session-observer-state.js +1 -0
  400. package/dist/session-toggles.js +2 -0
  401. package/dist/session-toggles.js.map +1 -1
  402. package/dist/signal.js +1 -0
  403. package/dist/skills-registry.js +2 -0
  404. package/dist/skills-registry.js.map +1 -1
  405. package/dist/source-attribution.js +1 -0
  406. package/dist/state-NCHQ4TRG.js +8 -0
  407. package/dist/state-NCHQ4TRG.js.map +1 -0
  408. package/dist/state-store-3EH7HYIN.js +16 -0
  409. package/dist/state-store-3EH7HYIN.js.map +1 -0
  410. package/dist/storage.d.ts +76 -2
  411. package/dist/storage.js +9 -6
  412. package/dist/store-contract.js +1 -0
  413. package/dist/summarizer.js +5 -4
  414. package/dist/summary-snapshot.js +1 -0
  415. package/dist/temporal-index.js +1 -0
  416. package/dist/temporal-supersession.d.ts +1 -1
  417. package/dist/temporal-supersession.js +2 -1
  418. package/dist/temporal-validity.d.ts +52 -0
  419. package/dist/temporal-validity.js +14 -0
  420. package/dist/temporal-validity.js.map +1 -0
  421. package/dist/threading.js +1 -0
  422. package/dist/tier-migration.d.ts +2 -2
  423. package/dist/tier-migration.js +1 -0
  424. package/dist/tier-routing.js +1 -0
  425. package/dist/tier-stats-62ZVDFKS.js +152 -0
  426. package/dist/tier-stats-62ZVDFKS.js.map +1 -0
  427. package/dist/tmt.js +1 -0
  428. package/dist/tokens.js +1 -0
  429. package/dist/topics.js +1 -0
  430. package/dist/trace-C5ETWBEF.js +290 -0
  431. package/dist/trace-C5ETWBEF.js.map +1 -0
  432. package/dist/transcript.js +1 -0
  433. package/dist/trust-zones.js +1 -0
  434. package/dist/tui-RI7P6PBS.js +13 -0
  435. package/dist/tui-RI7P6PBS.js.map +1 -0
  436. package/dist/types-V3FJ26TF.js +30 -0
  437. package/dist/types-V3FJ26TF.js.map +1 -0
  438. package/dist/types.d.ts +634 -9
  439. package/dist/types.js +10 -3
  440. package/dist/utility-learner.js +1 -0
  441. package/dist/utility-runtime.js +1 -0
  442. package/dist/utility-telemetry.js +1 -0
  443. package/dist/verified-recall.js +10 -7
  444. package/dist/version-utils.js +1 -0
  445. package/dist/whitespace.js +1 -0
  446. package/dist/work-product-ledger.js +1 -0
  447. package/package.json +7 -3
  448. package/scripts/ensure-better-sqlite3.mjs +124 -0
  449. package/dist/access-service-Br8ZydTK.d.ts +0 -827
  450. package/dist/chunk-3OGMS3PE.js.map +0 -1
  451. package/dist/chunk-3YGHKTBF.js.map +0 -1
  452. package/dist/chunk-6PFRXT4K.js.map +0 -1
  453. package/dist/chunk-6YJHX2DL.js.map +0 -1
  454. package/dist/chunk-BECYBZLX.js.map +0 -1
  455. package/dist/chunk-C2EFFULQ.js.map +0 -1
  456. package/dist/chunk-CUPFXL3J.js.map +0 -1
  457. package/dist/chunk-DIXB44VE.js.map +0 -1
  458. package/dist/chunk-F5VP6YCB.js.map +0 -1
  459. package/dist/chunk-FVA6TGI3.js.map +0 -1
  460. package/dist/chunk-GA5P7RST.js.map +0 -1
  461. package/dist/chunk-KVBLZUKV.js.map +0 -1
  462. package/dist/chunk-L7IXWRYE.js.map +0 -1
  463. package/dist/chunk-LOIMBRDE.js.map +0 -1
  464. package/dist/chunk-LTCGGW2D.js +0 -14
  465. package/dist/chunk-LTCGGW2D.js.map +0 -1
  466. package/dist/chunk-NZLQTHS5.js.map +0 -1
  467. package/dist/chunk-OC5OXUQ4.js.map +0 -1
  468. package/dist/chunk-PVPWZSSI.js.map +0 -1
  469. package/dist/chunk-SPI27QT6.js.map +0 -1
  470. package/dist/chunk-STGWEHYR.js.map +0 -1
  471. package/dist/chunk-TP4FZJIZ.js.map +0 -1
  472. package/dist/chunk-ULYOGL6R.js.map +0 -1
  473. package/dist/chunk-UWB5LMWY.js.map +0 -1
  474. package/dist/chunk-VBVG2M5G.js.map +0 -1
  475. package/dist/chunk-VDX363PS.js.map +0 -1
  476. package/dist/chunk-WCLICCGB.js.map +0 -1
  477. package/dist/chunk-X6GF3FX2.js +0 -26
  478. package/dist/chunk-X6GF3FX2.js.map +0 -1
  479. package/dist/chunk-XXVWLXSG.js.map +0 -1
  480. package/dist/chunk-Y7R2XJ5Q.js.map +0 -1
  481. package/dist/chunk-ZAIM4TUE.js.map +0 -1
  482. package/dist/engine-72LSIWQP.js +0 -23
  483. /package/dist/{contradiction-review-WIUBAR52.js.map → capsule-cli.js.map} +0 -0
  484. /package/dist/{engine-72LSIWQP.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
  485. /package/dist/{chunk-TMYO7B5P.js.map → chunk-47WOM4YW.js.map} +0 -0
  486. /package/dist/{chunk-DG6YMRDC.js.map → chunk-B2TL6GA2.js.map} +0 -0
  487. /package/dist/{chunk-AYXIPSZO.js.map → chunk-CRU27Q4J.js.map} +0 -0
  488. /package/dist/{chunk-RBBWYEFJ.js.map → chunk-G2WADRQ3.js.map} +0 -0
  489. /package/dist/{chunk-NBVAS5MT.js.map → chunk-V7TEH5I2.js.map} +0 -0
@@ -0,0 +1,153 @@
1
+ /**
2
+ * @remnic/core — Live Connectors Framework (issue #683 PR 1/N)
3
+ *
4
+ * Defines the contract that every "live" connector (Drive, Notion, Gmail,
5
+ * GitHub, ...) must satisfy. A live connector is **continuous**: it runs on a
6
+ * schedule, persists a cursor to disk, and ingests *new* documents since the
7
+ * last sync. This is distinct from one-shot importers in
8
+ * `packages/remnic-core/src/importers/` which transform an entire export file
9
+ * in a single pass.
10
+ *
11
+ * This module is intentionally pure types + interfaces. No I/O. No schedule
12
+ * wiring. Concrete connectors (PRs 2–5), the maintenance scheduler hookup
13
+ * (separate PR), and the CLI surface (PR 6) are deferred.
14
+ *
15
+ * Naming caveat: `packages/remnic-core/src/connectors/` is already scoped to
16
+ * the Codex marketplace integration. The live-connector framework lives under
17
+ * the `live/` subdirectory to avoid collision. Do not import Codex symbols
18
+ * from here, and do not import live-connector symbols from the Codex code.
19
+ */
20
+ /**
21
+ * Free-form connector configuration. Validated by each connector's
22
+ * `validateConfig` implementation. Stored alongside the cursor in the state
23
+ * store. MUST be JSON-serializable: no functions, no class instances, no
24
+ * circular references.
25
+ *
26
+ * Connectors MUST NOT persist secrets here — credentials belong in OS keychain
27
+ * / OAuth token storage (PR 2 design).
28
+ */
29
+ type ConnectorConfig = Record<string, unknown>;
30
+ /**
31
+ * Opaque cursor describing "where the last sync left off". Each connector
32
+ * defines what `kind` and `value` mean (e.g. Drive: `{kind: "pageToken",
33
+ * value: "..."}`, Gmail: `{kind: "historyId", value: "..."}`). The orchestrator
34
+ * treats it as opaque and only round-trips it through the state store.
35
+ *
36
+ * `updatedAt` is an ISO 8601 timestamp set by the framework when the cursor is
37
+ * written. It is informational — connectors MUST NOT use it to decide
38
+ * monotonicity. They own the `value` semantics.
39
+ */
40
+ interface ConnectorCursor {
41
+ /** Connector-defined cursor kind (e.g. `"pageToken"`, `"historyId"`, `"sinceTs"`). */
42
+ readonly kind: string;
43
+ /** Connector-defined opaque cursor value. */
44
+ readonly value: string;
45
+ /** ISO 8601 timestamp of when this cursor was last written. */
46
+ readonly updatedAt: string;
47
+ }
48
+ /**
49
+ * Provenance for a connector-ingested document. Required so downstream recall
50
+ * can attribute facts back to their origin and avoid re-ingesting on the next
51
+ * incremental pass.
52
+ */
53
+ interface ConnectorDocumentSource {
54
+ /** Stable connector id (matches `LiveConnector.id`). */
55
+ readonly connector: string;
56
+ /** Source-system identifier (Drive file id, Notion page id, Gmail msg id, ...). */
57
+ readonly externalId: string;
58
+ /** Optional source-system revision/version (etag, page version, history id). */
59
+ readonly externalRevision?: string;
60
+ /** Optional canonical URL pointing back at the source document. */
61
+ readonly externalUrl?: string;
62
+ /** ISO 8601 timestamp of when the connector fetched this document. */
63
+ readonly fetchedAt: string;
64
+ }
65
+ /**
66
+ * A single document yielded by an incremental sync. Connectors are responsible
67
+ * for chunking large source documents themselves if needed; the orchestrator
68
+ * ingests `content` as a unit.
69
+ */
70
+ interface ConnectorDocument {
71
+ /** Connector-local stable id for this document. SHOULD match `source.externalId`. */
72
+ readonly id: string;
73
+ /** Optional human-readable title. */
74
+ readonly title?: string;
75
+ /** Body content. Plaintext or Markdown — connectors document their format. */
76
+ readonly content: string;
77
+ /** Provenance. Required. */
78
+ readonly source: ConnectorDocumentSource;
79
+ }
80
+ /**
81
+ * Arguments passed to `syncIncremental`. The framework owns cursor/config
82
+ * lifecycle; connectors only read these and return the next cursor.
83
+ */
84
+ interface SyncIncrementalArgs {
85
+ /** Last persisted cursor, or `null` on the first ever sync. */
86
+ readonly cursor: ConnectorCursor | null;
87
+ /** Validated connector config (already passed through `validateConfig`). */
88
+ readonly config: ConnectorConfig;
89
+ /** Optional abort signal. Connectors SHOULD honor it for cooperative cancellation. */
90
+ readonly abortSignal?: AbortSignal;
91
+ }
92
+ /**
93
+ * Result of a single incremental sync pass.
94
+ *
95
+ * `newDocs` MAY be empty (no new documents since the last cursor). `nextCursor`
96
+ * MUST always be returned — even on no-op syncs the framework persists it so
97
+ * `updatedAt` reflects the most recent attempt.
98
+ */
99
+ interface SyncIncrementalResult {
100
+ readonly newDocs: ConnectorDocument[];
101
+ readonly nextCursor: ConnectorCursor;
102
+ }
103
+ /**
104
+ * The contract every live connector implements.
105
+ *
106
+ * Connectors MUST be:
107
+ * - **Idempotent**: re-running with the same cursor MUST NOT duplicate
108
+ * documents. The `source.externalId` + `source.externalRevision` pair is
109
+ * used downstream for dedup.
110
+ * - **Read-only on the source**: live connectors never mutate the upstream
111
+ * system (no marking emails read, no editing Notion pages).
112
+ * - **Cancellable**: long-running syncs SHOULD periodically check
113
+ * `abortSignal.aborted` and bail cleanly.
114
+ * - **Privacy-aware**: connectors MUST NOT log document content. Logging
115
+ * metadata (counts, ids, timings) is fine.
116
+ */
117
+ interface LiveConnector {
118
+ /**
119
+ * Stable connector id. MUST match `CONNECTOR_ID_PATTERN` — lowercase
120
+ * alphanumeric plus dash, 1–64 chars, must start AND end with alphanumeric
121
+ * (no leading or trailing dash). The registry enforces this.
122
+ */
123
+ readonly id: string;
124
+ /** Short human-readable name shown in CLI / status output. */
125
+ readonly displayName: string;
126
+ /** Optional longer description. */
127
+ readonly description?: string;
128
+ /**
129
+ * Validate raw user-supplied config. MUST throw on malformed input — never
130
+ * silently default. The returned object is what gets persisted and passed
131
+ * back to `syncIncremental`. Connectors SHOULD strip unknown fields.
132
+ */
133
+ validateConfig(raw: unknown): ConnectorConfig;
134
+ /**
135
+ * Run one incremental sync pass. See `SyncIncrementalArgs` /
136
+ * `SyncIncrementalResult` for the contract.
137
+ */
138
+ syncIncremental(args: SyncIncrementalArgs): Promise<SyncIncrementalResult>;
139
+ }
140
+ /**
141
+ * Regex enforcing the connector-id naming rule. Exported so connectors and
142
+ * tests can validate ids consistently with the registry.
143
+ *
144
+ * Rule: lowercase alphanumeric + dash, 1..64 chars, must start AND end with
145
+ * alphanumeric (no leading or trailing dash). Single-char ids are allowed.
146
+ */
147
+ declare const CONNECTOR_ID_PATTERN: RegExp;
148
+ /**
149
+ * Returns `true` if `id` is a syntactically valid connector id.
150
+ */
151
+ declare function isValidConnectorId(id: unknown): id is string;
152
+
153
+ export { type ConnectorConfig as C, type LiveConnector as L, type SyncIncrementalResult as S, type ConnectorDocument as a, type ConnectorCursor as b, CONNECTOR_ID_PATTERN as c, type ConnectorDocumentSource as d, type SyncIncrementalArgs as e, isValidConnectorId as i };
@@ -0,0 +1,30 @@
1
+ import {
2
+ assertIsDirectoryNotSymlink,
3
+ assertRealpathInsideRoot,
4
+ ensureDirExists,
5
+ fileExists,
6
+ fromPosixRelPath,
7
+ isPathInsideRoot,
8
+ listFilesRecursive,
9
+ readJsonFile,
10
+ sha256File,
11
+ sha256String,
12
+ toPosixRelPath,
13
+ writeJsonFile
14
+ } from "./chunk-457A4P3L.js";
15
+ import "./chunk-PZ5AY32C.js";
16
+ export {
17
+ assertIsDirectoryNotSymlink,
18
+ assertRealpathInsideRoot,
19
+ ensureDirExists,
20
+ fileExists,
21
+ fromPosixRelPath,
22
+ isPathInsideRoot,
23
+ listFilesRecursive,
24
+ readJsonFile,
25
+ sha256File,
26
+ sha256String,
27
+ toPosixRelPath,
28
+ writeJsonFile
29
+ };
30
+ //# sourceMappingURL=fs-utils-IRVUFB6G.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -2,6 +2,7 @@ import {
2
2
  diffGraphSnapshots
3
3
  } from "./chunk-3SLRNYNG.js";
4
4
  import "./chunk-Y4Z4I6WK.js";
5
+ import "./chunk-PZ5AY32C.js";
5
6
  export {
6
7
  diffGraphSnapshots
7
8
  };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  graphEdgeKey
3
3
  } from "./chunk-Y4Z4I6WK.js";
4
+ import "./chunk-PZ5AY32C.js";
4
5
  export {
5
6
  graphEdgeKey
6
7
  };
@@ -2,6 +2,7 @@ import {
2
2
  graphSnapshotFromMemoryDir
3
3
  } from "./chunk-LIRZNNUP.js";
4
4
  import "./chunk-Y4Z4I6WK.js";
5
+ import "./chunk-PZ5AY32C.js";
5
6
  export {
6
7
  graphSnapshotFromMemoryDir
7
8
  };
@@ -0,0 +1,207 @@
1
+ import {
2
+ isSafeRouteNamespace
3
+ } from "./chunk-2LGMW3DJ.js";
4
+ import {
5
+ graphFilePath,
6
+ graphsDir,
7
+ readEdgesStrict,
8
+ withGraphWriteLock
9
+ } from "./chunk-RK2Y4XOM.js";
10
+ import {
11
+ DEFAULT_DECAY_FLOOR,
12
+ DEFAULT_DECAY_PER_WINDOW,
13
+ DEFAULT_DECAY_WINDOW_MS,
14
+ decayEdgeConfidence,
15
+ readEdgeConfidence
16
+ } from "./chunk-2LSZVONP.js";
17
+ import "./chunk-WIICJPET.js";
18
+ import "./chunk-PZ5AY32C.js";
19
+
20
+ // src/maintenance/graph-edge-decay.ts
21
+ import {
22
+ mkdir,
23
+ readdir,
24
+ readFile,
25
+ rename,
26
+ writeFile
27
+ } from "fs/promises";
28
+ import path from "path";
29
+ var DEFAULT_VISIBILITY_THRESHOLD = 0.2;
30
+ var GRAPH_TYPES = ["entity", "time", "causal"];
31
+ function graphEdgeDecayStatusPath(memoryDir) {
32
+ return path.join(memoryDir, "state", "graph-edge-decay-status.json");
33
+ }
34
+ async function writeJsonlAtomic(filePath, edges) {
35
+ await mkdir(path.dirname(filePath), { recursive: true });
36
+ const body = edges.length === 0 ? "" : edges.map((e) => JSON.stringify(e)).join("\n") + "\n";
37
+ const tempPath = `${filePath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
38
+ await writeFile(tempPath, body, "utf-8");
39
+ await rename(tempPath, filePath);
40
+ }
41
+ async function runGraphEdgeDecayMaintenance(memoryDir, options = {}) {
42
+ const startedAt = Date.now();
43
+ const ranAt = options.now ?? (/* @__PURE__ */ new Date()).toISOString();
44
+ const windowMs = options.windowMs ?? DEFAULT_DECAY_WINDOW_MS;
45
+ const perWindow = options.perWindow ?? DEFAULT_DECAY_PER_WINDOW;
46
+ const floor = options.floor ?? DEFAULT_DECAY_FLOOR;
47
+ const visibilityThreshold = typeof options.visibilityThreshold === "number" && Number.isFinite(options.visibilityThreshold) ? Math.max(0, Math.min(1, options.visibilityThreshold)) : DEFAULT_VISIBILITY_THRESHOLD;
48
+ const dryRun = options.dryRun === true;
49
+ await mkdir(graphsDir(memoryDir), { recursive: true });
50
+ const perType = [];
51
+ const dropByLabel = /* @__PURE__ */ new Map();
52
+ let edgesTotal = 0;
53
+ let edgesDecayed = 0;
54
+ let edgesBelowVisibilityThreshold = 0;
55
+ for (const type of GRAPH_TYPES) {
56
+ const filePath = graphFilePath(memoryDir, type);
57
+ const {
58
+ typeDecayed,
59
+ typeBelow,
60
+ typeTotal
61
+ } = await withGraphWriteLock(filePath, async () => {
62
+ const edges = await readEdgesStrict(memoryDir, type);
63
+ const updated = new Array(edges.length);
64
+ let localDecayed = 0;
65
+ let localBelow = 0;
66
+ let localChangedAny = false;
67
+ for (let i = 0; i < edges.length; i += 1) {
68
+ const edge = edges[i];
69
+ const before = readEdgeConfidence(edge);
70
+ const decayed = decayEdgeConfidence(edge, ranAt, { windowMs, perWindow, floor });
71
+ const after = readEdgeConfidence(decayed);
72
+ if (after < before) {
73
+ localDecayed += 1;
74
+ const drop = before - after;
75
+ const label = typeof edge.label === "string" ? edge.label : "";
76
+ if (label.length > 0) {
77
+ const prev = dropByLabel.get(label);
78
+ if (prev) {
79
+ prev.totalDrop += drop;
80
+ prev.edgeCount += 1;
81
+ } else {
82
+ dropByLabel.set(label, { totalDrop: drop, edgeCount: 1 });
83
+ }
84
+ }
85
+ }
86
+ if (after < visibilityThreshold) {
87
+ localBelow += 1;
88
+ }
89
+ updated[i] = decayed;
90
+ if (decayed.confidence !== edge.confidence || decayed.lastReinforcedAt !== edge.lastReinforcedAt) {
91
+ localChangedAny = true;
92
+ }
93
+ }
94
+ if (!dryRun && localChangedAny && edges.length > 0) {
95
+ await writeJsonlAtomic(filePath, updated);
96
+ }
97
+ return {
98
+ typeDecayed: localDecayed,
99
+ typeBelow: localBelow,
100
+ typeTotal: edges.length
101
+ };
102
+ });
103
+ edgesDecayed += typeDecayed;
104
+ edgesBelowVisibilityThreshold += typeBelow;
105
+ edgesTotal += typeTotal;
106
+ perType.push({
107
+ type,
108
+ edgesTotal: typeTotal,
109
+ edgesDecayed: typeDecayed,
110
+ edgesBelowVisibilityThreshold: typeBelow
111
+ });
112
+ }
113
+ const topDecayedEntities = [...dropByLabel.entries()].map(([label, agg]) => ({ label, totalDrop: agg.totalDrop, edgeCount: agg.edgeCount })).sort((a, b) => {
114
+ if (b.totalDrop !== a.totalDrop) return b.totalDrop - a.totalDrop;
115
+ return a.label.localeCompare(b.label);
116
+ }).slice(0, 5);
117
+ const telemetry = {
118
+ ranAt,
119
+ durationMs: Date.now() - startedAt,
120
+ edgesTotal,
121
+ edgesDecayed,
122
+ edgesBelowVisibilityThreshold,
123
+ topDecayedEntities,
124
+ perType,
125
+ windowMs,
126
+ perWindow,
127
+ floor,
128
+ visibilityThreshold
129
+ };
130
+ if (!dryRun) {
131
+ await persistTelemetry(memoryDir, telemetry);
132
+ }
133
+ return telemetry;
134
+ }
135
+ async function persistTelemetry(memoryDir, telemetry) {
136
+ const statusPath = graphEdgeDecayStatusPath(memoryDir);
137
+ await mkdir(path.dirname(statusPath), { recursive: true });
138
+ const tempPath = `${statusPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
139
+ try {
140
+ await writeFile(tempPath, JSON.stringify(telemetry, null, 2) + "\n", "utf-8");
141
+ await rename(tempPath, statusPath);
142
+ } catch {
143
+ }
144
+ }
145
+ async function readGraphEdgeDecayStatus(memoryDir) {
146
+ try {
147
+ const raw = await readFile(graphEdgeDecayStatusPath(memoryDir), "utf-8");
148
+ const parsed = JSON.parse(raw);
149
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
150
+ return null;
151
+ }
152
+ return parsed;
153
+ } catch {
154
+ return null;
155
+ }
156
+ }
157
+ async function discoverGraphNamespaceRoots(memoryDir, options) {
158
+ const seen = /* @__PURE__ */ new Map();
159
+ seen.set(options.defaultNamespace, memoryDir);
160
+ if (!options.namespacesEnabled) {
161
+ return [...seen.entries()].map(([namespace, storageRoot]) => ({ namespace, storageRoot }));
162
+ }
163
+ const namespacesDir = path.join(memoryDir, "namespaces");
164
+ let entries;
165
+ try {
166
+ entries = await readdir(namespacesDir, { withFileTypes: true });
167
+ } catch {
168
+ return [...seen.entries()].map(([namespace, storageRoot]) => ({ namespace, storageRoot }));
169
+ }
170
+ for (const entry of entries) {
171
+ if (!entry.isDirectory()) continue;
172
+ if (!isSafeRouteNamespace(entry.name)) continue;
173
+ const root = path.join(namespacesDir, entry.name);
174
+ seen.set(entry.name, root);
175
+ }
176
+ return [...seen.entries()].map(([namespace, storageRoot]) => ({ namespace, storageRoot }));
177
+ }
178
+ async function runGraphEdgeDecayMaintenanceAcrossNamespaces(memoryDir, options) {
179
+ const { namespacesEnabled, defaultNamespace, ...decayOptions } = options;
180
+ const roots = await discoverGraphNamespaceRoots(memoryDir, {
181
+ namespacesEnabled,
182
+ defaultNamespace
183
+ });
184
+ const results = [];
185
+ for (const { namespace, storageRoot } of roots) {
186
+ try {
187
+ const telemetry = await runGraphEdgeDecayMaintenance(storageRoot, decayOptions);
188
+ results.push({ namespace, storageRoot, telemetry });
189
+ } catch (err) {
190
+ results.push({
191
+ namespace,
192
+ storageRoot,
193
+ error: err instanceof Error ? err.message : String(err)
194
+ });
195
+ }
196
+ }
197
+ return results;
198
+ }
199
+ export {
200
+ DEFAULT_VISIBILITY_THRESHOLD,
201
+ discoverGraphNamespaceRoots,
202
+ graphEdgeDecayStatusPath,
203
+ readGraphEdgeDecayStatus,
204
+ runGraphEdgeDecayMaintenance,
205
+ runGraphEdgeDecayMaintenanceAcrossNamespaces
206
+ };
207
+ //# sourceMappingURL=graph-edge-decay-PWB63GRE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/maintenance/graph-edge-decay.ts"],"sourcesContent":["/**\n * Graph-edge decay maintenance job (issue #681 PR 2/3).\n *\n * For each edge in the on-disk JSONL graph stores\n * (`<memoryDir>/state/graphs/{entity,time,causal}.jsonl`) call\n * {@link decayEdgeConfidence} from PR 1/3 and write the decayed edge\n * back to disk via the temp+rename atomic-replace pattern (CLAUDE.md\n * gotcha #54: never delete-before-write).\n *\n * Emits a structured telemetry record per run that the doctor surface\n * (`remnic doctor`) and a tail of the maintenance ledger can consume.\n *\n * Pure-helper-style API (the function takes a `memoryDir` + opts and\n * returns a record); callers wire the cron / MCP tool / CLI surfaces.\n */\n\nimport {\n mkdir,\n readdir,\n readFile,\n rename,\n writeFile,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n decayEdgeConfidence,\n DEFAULT_DECAY_FLOOR,\n DEFAULT_DECAY_PER_WINDOW,\n DEFAULT_DECAY_WINDOW_MS,\n readEdgeConfidence,\n type DecayOptions,\n} from \"../graph-edge-reinforcement.js\";\nimport {\n graphFilePath,\n graphsDir,\n readEdgesStrict,\n withGraphWriteLock,\n type GraphEdge,\n type GraphType,\n} from \"../graph.js\";\nimport { isSafeRouteNamespace } from \"../routing/engine.js\";\n\n/** Default visibility threshold for the \"below visibility\" telemetry counter. */\nexport const DEFAULT_VISIBILITY_THRESHOLD = 0.2;\n\nconst GRAPH_TYPES: readonly GraphType[] = [\"entity\", \"time\", \"causal\"] as const;\n\n/** Per-edge-type breakdown emitted by {@link runGraphEdgeDecayMaintenance}. */\nexport interface GraphEdgeDecayPerTypeStats {\n type: GraphType;\n edgesTotal: number;\n edgesDecayed: number;\n edgesBelowVisibilityThreshold: number;\n}\n\n/** Top-decayed-entity entry (label + total confidence drop summed across edges). */\nexport interface GraphEdgeDecayTopEntity {\n label: string;\n totalDrop: number;\n edgeCount: number;\n}\n\n/**\n * Telemetry record emitted by every run of the decay job. Persisted to\n * `<memoryDir>/state/graph-edge-decay-status.json` for doctor consumption\n * and (optionally) appended to the maintenance ledger by callers.\n */\nexport interface GraphEdgeDecayTelemetry {\n ranAt: string;\n durationMs: number;\n edgesTotal: number;\n edgesDecayed: number;\n edgesBelowVisibilityThreshold: number;\n topDecayedEntities: GraphEdgeDecayTopEntity[];\n perType: GraphEdgeDecayPerTypeStats[];\n windowMs: number;\n perWindow: number;\n floor: number;\n visibilityThreshold: number;\n}\n\nexport interface GraphEdgeDecayOptions extends DecayOptions {\n /** Confidence threshold below which an edge counts as \"low visibility\". */\n visibilityThreshold?: number;\n /** Override \"now\" for deterministic testing. Defaults to `new Date().toISOString()`. */\n now?: string;\n /** When `true`, do not write decayed edges back — just compute telemetry. */\n dryRun?: boolean;\n}\n\n/** Path of the latest-run status file. */\nexport function graphEdgeDecayStatusPath(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"graph-edge-decay-status.json\");\n}\n\n/** Write a JSONL file atomically using temp+rename (CLAUDE.md gotcha #54). */\nasync function writeJsonlAtomic(filePath: string, edges: GraphEdge[]): Promise<void> {\n await mkdir(path.dirname(filePath), { recursive: true });\n const body = edges.length === 0 ? \"\" : edges.map((e) => JSON.stringify(e)).join(\"\\n\") + \"\\n\";\n // Codex P2 / gotcha #54: write to temp then rename. Never rmSync(target)\n // before the rename succeeds; rename is atomic on the same filesystem.\n // Include pid + monotonic-ish suffix so concurrent runs cannot collide.\n const tempPath = `${filePath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;\n await writeFile(tempPath, body, \"utf-8\");\n await rename(tempPath, filePath);\n}\n\n/**\n * Run a single decay pass over every edge type.\n *\n * Idempotency: PR 1/3's `decayEdgeConfidence` advances `lastReinforcedAt`\n * by exactly the windows it just charged for, so a second run with the\n * same `now` (or any `now` inside the new grace window) is a no-op.\n *\n * Returns the telemetry record. The record is also persisted to\n * {@link graphEdgeDecayStatusPath} so doctor / CLI can read the last run\n * without re-scanning the graphs.\n */\nexport async function runGraphEdgeDecayMaintenance(\n memoryDir: string,\n options: GraphEdgeDecayOptions = {},\n): Promise<GraphEdgeDecayTelemetry> {\n const startedAt = Date.now();\n const ranAt = options.now ?? new Date().toISOString();\n const windowMs = options.windowMs ?? DEFAULT_DECAY_WINDOW_MS;\n const perWindow = options.perWindow ?? DEFAULT_DECAY_PER_WINDOW;\n const floor = options.floor ?? DEFAULT_DECAY_FLOOR;\n const visibilityThreshold =\n typeof options.visibilityThreshold === \"number\" && Number.isFinite(options.visibilityThreshold)\n ? Math.max(0, Math.min(1, options.visibilityThreshold))\n : DEFAULT_VISIBILITY_THRESHOLD;\n const dryRun = options.dryRun === true;\n\n await mkdir(graphsDir(memoryDir), { recursive: true });\n\n const perType: GraphEdgeDecayPerTypeStats[] = [];\n // Aggregate per-label decay drops across ALL graph types so the\n // \"top decayed entities\" list reflects whichever label dominated\n // each edge (entity name, threadId, or causal phrase). Sorting by\n // total confidence drop highlights the edges decay actually moved\n // most in this pass.\n const dropByLabel = new Map<string, { totalDrop: number; edgeCount: number }>();\n\n let edgesTotal = 0;\n let edgesDecayed = 0;\n let edgesBelowVisibilityThreshold = 0;\n\n for (const type of GRAPH_TYPES) {\n const filePath = graphFilePath(memoryDir, type);\n\n // Hold the per-graph-file write lock across BOTH the read-snapshot\n // and the atomic rewrite so concurrent `appendEdge()` calls cannot\n // sneak in between (issue #729 / Codex P1, line 224). Without this\n // lock the snapshot rewrite would silently drop any edge appended\n // by extraction during the same window. Read failures other than\n // ENOENT are surfaced via `readEdgesStrict` so I/O outages cannot\n // be reported as \"no edges to decay\" (Codex P1, line 120).\n const {\n typeDecayed,\n typeBelow,\n typeTotal,\n } = await withGraphWriteLock(filePath, async () => {\n const edges = await readEdgesStrict(memoryDir, type);\n const updated: GraphEdge[] = new Array(edges.length);\n\n let localDecayed = 0;\n let localBelow = 0;\n let localChangedAny = false;\n\n for (let i = 0; i < edges.length; i += 1) {\n const edge = edges[i];\n const before = readEdgeConfidence(edge);\n const decayed = decayEdgeConfidence(edge, ranAt, { windowMs, perWindow, floor });\n const after = readEdgeConfidence(decayed);\n\n // Only count as \"decayed\" when the confidence actually dropped.\n // `decayEdgeConfidence` may return an unchanged copy (still inside\n // the grace window, or already at/below the floor) — those are\n // visited but not decayed.\n if (after < before) {\n localDecayed += 1;\n const drop = before - after;\n const label = typeof edge.label === \"string\" ? edge.label : \"\";\n // Skip empty labels in the top list — surfacing them produces\n // a meaningless \"\" entry that crowds the report.\n if (label.length > 0) {\n const prev = dropByLabel.get(label);\n if (prev) {\n prev.totalDrop += drop;\n prev.edgeCount += 1;\n } else {\n dropByLabel.set(label, { totalDrop: drop, edgeCount: 1 });\n }\n }\n }\n if (after < visibilityThreshold) {\n localBelow += 1;\n }\n updated[i] = decayed;\n // Detect any structural change (confidence OR lastReinforcedAt anchor advance)\n // so we only rewrite the JSONL when there's something to persist.\n if (\n decayed.confidence !== edge.confidence ||\n decayed.lastReinforcedAt !== edge.lastReinforcedAt\n ) {\n localChangedAny = true;\n }\n }\n\n if (!dryRun && localChangedAny && edges.length > 0) {\n await writeJsonlAtomic(filePath, updated);\n }\n\n return {\n typeDecayed: localDecayed,\n typeBelow: localBelow,\n typeTotal: edges.length,\n };\n });\n\n edgesDecayed += typeDecayed;\n edgesBelowVisibilityThreshold += typeBelow;\n edgesTotal += typeTotal;\n perType.push({\n type,\n edgesTotal: typeTotal,\n edgesDecayed: typeDecayed,\n edgesBelowVisibilityThreshold: typeBelow,\n });\n }\n\n // Stable secondary key on label keeps ordering deterministic when two\n // labels happen to have exactly the same totalDrop (gotcha #19).\n const topDecayedEntities: GraphEdgeDecayTopEntity[] = [...dropByLabel.entries()]\n .map(([label, agg]) => ({ label, totalDrop: agg.totalDrop, edgeCount: agg.edgeCount }))\n .sort((a, b) => {\n if (b.totalDrop !== a.totalDrop) return b.totalDrop - a.totalDrop;\n return a.label.localeCompare(b.label);\n })\n .slice(0, 5);\n\n const telemetry: GraphEdgeDecayTelemetry = {\n ranAt,\n durationMs: Date.now() - startedAt,\n edgesTotal,\n edgesDecayed,\n edgesBelowVisibilityThreshold,\n topDecayedEntities,\n perType,\n windowMs,\n perWindow,\n floor,\n visibilityThreshold,\n };\n\n if (!dryRun) {\n await persistTelemetry(memoryDir, telemetry);\n }\n\n return telemetry;\n}\n\nasync function persistTelemetry(\n memoryDir: string,\n telemetry: GraphEdgeDecayTelemetry,\n): Promise<void> {\n const statusPath = graphEdgeDecayStatusPath(memoryDir);\n await mkdir(path.dirname(statusPath), { recursive: true });\n const tempPath = `${statusPath}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;\n // Wrap I/O in try/catch (gotcha #13) — failing to persist telemetry must\n // not blow up the maintenance run; the in-memory record is still returned.\n try {\n await writeFile(tempPath, JSON.stringify(telemetry, null, 2) + \"\\n\", \"utf-8\");\n await rename(tempPath, statusPath);\n } catch {\n // Best-effort: callers still receive the in-memory telemetry record.\n }\n}\n\n/** Read the last persisted decay-run telemetry, if any. */\nexport async function readGraphEdgeDecayStatus(\n memoryDir: string,\n): Promise<GraphEdgeDecayTelemetry | null> {\n try {\n const raw = await readFile(graphEdgeDecayStatusPath(memoryDir), \"utf-8\");\n const parsed = JSON.parse(raw);\n // Validate the parsed payload is a plain object (gotcha #18: JSON.parse('null') is valid).\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n return null;\n }\n return parsed as GraphEdgeDecayTelemetry;\n } catch {\n return null;\n }\n}\n\n/**\n * Per-namespace telemetry record returned by\n * {@link runGraphEdgeDecayMaintenanceAcrossNamespaces}. Each entry\n * pairs the namespace name with its decay telemetry (or an error\n * string if that namespace's run failed). Allows operators to spot\n * I/O outages on a single namespace without masking the rest.\n */\nexport interface GraphEdgeDecayNamespaceResult {\n namespace: string;\n storageRoot: string;\n telemetry?: GraphEdgeDecayTelemetry;\n error?: string;\n}\n\n/**\n * Discover every namespace storage root that may contain graph files.\n *\n * Returns a list of `{ namespace, storageRoot }` entries:\n * - The default namespace at `memoryDir` (always present).\n * - Each subdirectory under `memoryDir/namespaces/` that passes\n * `isSafeRouteNamespace`.\n *\n * Per gotcha #42: read paths must enumerate the same namespace layer\n * as write paths so non-default namespaces don't get skipped during\n * maintenance. Issue #729 / Codex P2.\n */\nexport async function discoverGraphNamespaceRoots(\n memoryDir: string,\n options: { namespacesEnabled: boolean; defaultNamespace: string },\n): Promise<{ namespace: string; storageRoot: string }[]> {\n const seen = new Map<string, string>();\n // Default namespace always lives at memoryDir (NamespaceStorageRouter\n // falls back to memoryDir when memoryDir/namespaces/<default> does\n // not exist).\n seen.set(options.defaultNamespace, memoryDir);\n\n if (!options.namespacesEnabled) {\n return [...seen.entries()].map(([namespace, storageRoot]) => ({ namespace, storageRoot }));\n }\n\n const namespacesDir = path.join(memoryDir, \"namespaces\");\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = await readdir(namespacesDir, { withFileTypes: true });\n } catch {\n // No namespaces dir yet — only the default namespace exists.\n return [...seen.entries()].map(([namespace, storageRoot]) => ({ namespace, storageRoot }));\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (!isSafeRouteNamespace(entry.name)) continue;\n const root = path.join(namespacesDir, entry.name);\n seen.set(entry.name, root);\n }\n\n return [...seen.entries()].map(([namespace, storageRoot]) => ({ namespace, storageRoot }));\n}\n\n/**\n * Run the decay maintenance pass against every namespace storage root.\n *\n * In namespaces-enabled deployments, non-default namespaces store\n * their graph JSONLs under `memoryDir/namespaces/<ns>/state/graphs/`,\n * so a single-root run only updates the default namespace and silently\n * skips the rest (issue #729 / Codex P2).\n *\n * Failures in one namespace do not block other namespaces; per-root\n * errors are surfaced in the `error` field of each result.\n */\nexport async function runGraphEdgeDecayMaintenanceAcrossNamespaces(\n memoryDir: string,\n options: GraphEdgeDecayOptions & {\n namespacesEnabled: boolean;\n defaultNamespace: string;\n },\n): Promise<GraphEdgeDecayNamespaceResult[]> {\n const { namespacesEnabled, defaultNamespace, ...decayOptions } = options;\n const roots = await discoverGraphNamespaceRoots(memoryDir, {\n namespacesEnabled,\n defaultNamespace,\n });\n\n const results: GraphEdgeDecayNamespaceResult[] = [];\n for (const { namespace, storageRoot } of roots) {\n try {\n const telemetry = await runGraphEdgeDecayMaintenance(storageRoot, decayOptions);\n results.push({ namespace, storageRoot, telemetry });\n } catch (err) {\n results.push({\n namespace,\n storageRoot,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n return results;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAgBA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAO,UAAU;AAqBV,IAAM,+BAA+B;AAE5C,IAAM,cAAoC,CAAC,UAAU,QAAQ,QAAQ;AA8C9D,SAAS,yBAAyB,WAA2B;AAClE,SAAO,KAAK,KAAK,WAAW,SAAS,8BAA8B;AACrE;AAGA,eAAe,iBAAiB,UAAkB,OAAmC;AACnF,QAAM,MAAM,KAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAM,OAAO,MAAM,WAAW,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,IAAI;AAIxF,QAAM,WAAW,GAAG,QAAQ,IAAI,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAChG,QAAM,UAAU,UAAU,MAAM,OAAO;AACvC,QAAM,OAAO,UAAU,QAAQ;AACjC;AAaA,eAAsB,6BACpB,WACA,UAAiC,CAAC,GACA;AAClC,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,QAAQ,QAAQ,QAAO,oBAAI,KAAK,GAAE,YAAY;AACpD,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,sBACJ,OAAO,QAAQ,wBAAwB,YAAY,OAAO,SAAS,QAAQ,mBAAmB,IAC1F,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,mBAAmB,CAAC,IACpD;AACN,QAAM,SAAS,QAAQ,WAAW;AAElC,QAAM,MAAM,UAAU,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAErD,QAAM,UAAwC,CAAC;AAM/C,QAAM,cAAc,oBAAI,IAAsD;AAE9E,MAAI,aAAa;AACjB,MAAI,eAAe;AACnB,MAAI,gCAAgC;AAEpC,aAAW,QAAQ,aAAa;AAC9B,UAAM,WAAW,cAAc,WAAW,IAAI;AAS9C,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,MAAM,mBAAmB,UAAU,YAAY;AACjD,YAAM,QAAQ,MAAM,gBAAgB,WAAW,IAAI;AACnD,YAAM,UAAuB,IAAI,MAAM,MAAM,MAAM;AAEnD,UAAI,eAAe;AACnB,UAAI,aAAa;AACjB,UAAI,kBAAkB;AAEtB,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,cAAM,OAAO,MAAM,CAAC;AACpB,cAAM,SAAS,mBAAmB,IAAI;AACtC,cAAM,UAAU,oBAAoB,MAAM,OAAO,EAAE,UAAU,WAAW,MAAM,CAAC;AAC/E,cAAM,QAAQ,mBAAmB,OAAO;AAMxC,YAAI,QAAQ,QAAQ;AAClB,0BAAgB;AAChB,gBAAM,OAAO,SAAS;AACtB,gBAAM,QAAQ,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAG5D,cAAI,MAAM,SAAS,GAAG;AACpB,kBAAM,OAAO,YAAY,IAAI,KAAK;AAClC,gBAAI,MAAM;AACR,mBAAK,aAAa;AAClB,mBAAK,aAAa;AAAA,YACpB,OAAO;AACL,0BAAY,IAAI,OAAO,EAAE,WAAW,MAAM,WAAW,EAAE,CAAC;AAAA,YAC1D;AAAA,UACF;AAAA,QACF;AACA,YAAI,QAAQ,qBAAqB;AAC/B,wBAAc;AAAA,QAChB;AACA,gBAAQ,CAAC,IAAI;AAGb,YACE,QAAQ,eAAe,KAAK,cAC5B,QAAQ,qBAAqB,KAAK,kBAClC;AACA,4BAAkB;AAAA,QACpB;AAAA,MACF;AAEA,UAAI,CAAC,UAAU,mBAAmB,MAAM,SAAS,GAAG;AAClD,cAAM,iBAAiB,UAAU,OAAO;AAAA,MAC1C;AAEA,aAAO;AAAA,QACL,aAAa;AAAA,QACb,WAAW;AAAA,QACX,WAAW,MAAM;AAAA,MACnB;AAAA,IACF,CAAC;AAED,oBAAgB;AAChB,qCAAiC;AACjC,kBAAc;AACd,YAAQ,KAAK;AAAA,MACX;AAAA,MACA,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,+BAA+B;AAAA,IACjC,CAAC;AAAA,EACH;AAIA,QAAM,qBAAgD,CAAC,GAAG,YAAY,QAAQ,CAAC,EAC5E,IAAI,CAAC,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,WAAW,IAAI,WAAW,WAAW,IAAI,UAAU,EAAE,EACrF,KAAK,CAAC,GAAG,MAAM;AACd,QAAI,EAAE,cAAc,EAAE,UAAW,QAAO,EAAE,YAAY,EAAE;AACxD,WAAO,EAAE,MAAM,cAAc,EAAE,KAAK;AAAA,EACtC,CAAC,EACA,MAAM,GAAG,CAAC;AAEb,QAAM,YAAqC;AAAA,IACzC;AAAA,IACA,YAAY,KAAK,IAAI,IAAI;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ;AACX,UAAM,iBAAiB,WAAW,SAAS;AAAA,EAC7C;AAEA,SAAO;AACT;AAEA,eAAe,iBACb,WACA,WACe;AACf,QAAM,aAAa,yBAAyB,SAAS;AACrD,QAAM,MAAM,KAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AACzD,QAAM,WAAW,GAAG,UAAU,IAAI,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAGlG,MAAI;AACF,UAAM,UAAU,UAAU,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI,MAAM,OAAO;AAC5E,UAAM,OAAO,UAAU,UAAU;AAAA,EACnC,QAAQ;AAAA,EAER;AACF;AAGA,eAAsB,yBACpB,WACyC;AACzC,MAAI;AACF,UAAM,MAAM,MAAM,SAAS,yBAAyB,SAAS,GAAG,OAAO;AACvE,UAAM,SAAS,KAAK,MAAM,GAAG;AAE7B,QAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,MAAM,GAAG;AAC1E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA4BA,eAAsB,4BACpB,WACA,SACuD;AACvD,QAAM,OAAO,oBAAI,IAAoB;AAIrC,OAAK,IAAI,QAAQ,kBAAkB,SAAS;AAE5C,MAAI,CAAC,QAAQ,mBAAmB;AAC9B,WAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,WAAW,OAAO,EAAE,WAAW,YAAY,EAAE;AAAA,EAC3F;AAEA,QAAM,gBAAgB,KAAK,KAAK,WAAW,YAAY;AACvD,MAAI;AACJ,MAAI;AACF,cAAU,MAAM,QAAQ,eAAe,EAAE,eAAe,KAAK,CAAC;AAAA,EAChE,QAAQ;AAEN,WAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,WAAW,OAAO,EAAE,WAAW,YAAY,EAAE;AAAA,EAC3F;AACA,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,YAAY,EAAG;AAC1B,QAAI,CAAC,qBAAqB,MAAM,IAAI,EAAG;AACvC,UAAM,OAAO,KAAK,KAAK,eAAe,MAAM,IAAI;AAChD,SAAK,IAAI,MAAM,MAAM,IAAI;AAAA,EAC3B;AAEA,SAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,WAAW,WAAW,OAAO,EAAE,WAAW,YAAY,EAAE;AAC3F;AAaA,eAAsB,6CACpB,WACA,SAI0C;AAC1C,QAAM,EAAE,mBAAmB,kBAAkB,GAAG,aAAa,IAAI;AACjE,QAAM,QAAQ,MAAM,4BAA4B,WAAW;AAAA,IACzD;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,UAA2C,CAAC;AAClD,aAAW,EAAE,WAAW,YAAY,KAAK,OAAO;AAC9C,QAAI;AACF,YAAM,YAAY,MAAM,6BAA6B,aAAa,YAAY;AAC9E,cAAQ,KAAK,EAAE,WAAW,aAAa,UAAU,CAAC;AAAA,IACpD,SAAS,KAAK;AACZ,cAAQ,KAAK;AAAA,QACX;AAAA,QACA;AAAA,QACA,OAAO,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
@@ -0,0 +1,81 @@
1
+ import { GraphEdge } from './graph.js';
2
+
3
+ /**
4
+ * Graph edge confidence + reinforcement primitives (issue #681, PR 1/3).
5
+ *
6
+ * Pure functions only — no I/O, no global state. The maintenance job (PR 2/3)
7
+ * and PageRank weighting (PR 3/3) compose these helpers.
8
+ *
9
+ * Schema:
10
+ * - `confidence` ∈ [0, 1]; missing on legacy edges, treated as 1.0.
11
+ * - `lastReinforcedAt` — ISO timestamp of most recent reinforcement; missing
12
+ * on legacy edges, treated as the original edge `ts`.
13
+ *
14
+ * Defaults documented here are the agreed-on starting points and may be
15
+ * tuned later via config. They live as named constants so call sites and
16
+ * tests share the same values.
17
+ */
18
+
19
+ /** Default confidence bump per reinforcement event. */
20
+ declare const DEFAULT_REINFORCE_DELTA = 0.05;
21
+ /** Maximum edge confidence — confidence is capped at this on reinforcement. */
22
+ declare const CONFIDENCE_CEILING = 1;
23
+ /** Default decay window in milliseconds (90 days). */
24
+ declare const DEFAULT_DECAY_WINDOW_MS: number;
25
+ /** Default decay floor — confidence will not drop below this purely from age. */
26
+ declare const DEFAULT_DECAY_FLOOR = 0.1;
27
+ /** Default per-window decay amount (linear). */
28
+ declare const DEFAULT_DECAY_PER_WINDOW = 0.1;
29
+ /**
30
+ * Treat a missing `confidence` on a legacy edge as 1.0.
31
+ * Clamps to `[0, CONFIDENCE_CEILING]` so downstream math is well-behaved.
32
+ */
33
+ declare function readEdgeConfidence(edge: Pick<GraphEdge, "confidence">): number;
34
+ /**
35
+ * Resolve the reference timestamp for decay calculations.
36
+ * Falls back to the edge's creation `ts` when `lastReinforcedAt` is absent
37
+ * (legacy edges have never been reinforced).
38
+ */
39
+ declare function readLastReinforcedAt(edge: Pick<GraphEdge, "lastReinforcedAt" | "ts">): string;
40
+ /**
41
+ * Reinforce an edge: bump confidence by `delta` (capped at 1.0) and stamp
42
+ * `lastReinforcedAt = now`. Pure — returns a new edge, never mutates input.
43
+ *
44
+ * Idempotency note: calling reinforceEdge twice with the same `now` and a
45
+ * delta of 0 returns an edge equal to the input (modulo timestamp).
46
+ *
47
+ * @param edge the edge to reinforce
48
+ * @param now ISO timestamp of the reinforcement event
49
+ * @param delta confidence bump; defaults to DEFAULT_REINFORCE_DELTA
50
+ */
51
+ declare function reinforceEdge(edge: GraphEdge, now: string, delta?: number): GraphEdge;
52
+ /** Options for {@link decayEdgeConfidence}. */
53
+ interface DecayOptions {
54
+ /** Decay window in milliseconds. Defaults to 90 days. */
55
+ windowMs?: number;
56
+ /** Per-window decay amount. Defaults to 0.1. */
57
+ perWindow?: number;
58
+ /** Floor confidence will not decay below. Defaults to 0.1. */
59
+ floor?: number;
60
+ }
61
+ /**
62
+ * Apply linear decay to an edge's confidence based on time since last
63
+ * reinforcement (or creation, for legacy edges). Pure — returns a new edge.
64
+ *
65
+ * Decay model:
66
+ * age = now - lastReinforcedAt
67
+ * if age <= windowMs: confidence unchanged
68
+ * else: confidence -= perWindow * floor((age - windowMs) / windowMs + 1)
69
+ * confidence is clamped to [floor, 1.0]
70
+ *
71
+ * Boundary semantics: `age === windowMs` is INSIDE the no-decay grace period
72
+ * (`<=`). Decay only kicks in once age strictly exceeds the window. This
73
+ * keeps the boundary deterministic and easy to test.
74
+ *
75
+ * @param edge edge to decay (confidence and lastReinforcedAt may be absent)
76
+ * @param now ISO timestamp representing "now"
77
+ * @param opts override window / per-window / floor; otherwise defaults are used
78
+ */
79
+ declare function decayEdgeConfidence(edge: GraphEdge, now: string, opts?: DecayOptions): GraphEdge;
80
+
81
+ export { CONFIDENCE_CEILING, DEFAULT_DECAY_FLOOR, DEFAULT_DECAY_PER_WINDOW, DEFAULT_DECAY_WINDOW_MS, DEFAULT_REINFORCE_DELTA, type DecayOptions, decayEdgeConfidence, readEdgeConfidence, readLastReinforcedAt, reinforceEdge };
@@ -0,0 +1,24 @@
1
+ import {
2
+ CONFIDENCE_CEILING,
3
+ DEFAULT_DECAY_FLOOR,
4
+ DEFAULT_DECAY_PER_WINDOW,
5
+ DEFAULT_DECAY_WINDOW_MS,
6
+ DEFAULT_REINFORCE_DELTA,
7
+ decayEdgeConfidence,
8
+ readEdgeConfidence,
9
+ readLastReinforcedAt,
10
+ reinforceEdge
11
+ } from "./chunk-2LSZVONP.js";
12
+ import "./chunk-PZ5AY32C.js";
13
+ export {
14
+ CONFIDENCE_CEILING,
15
+ DEFAULT_DECAY_FLOOR,
16
+ DEFAULT_DECAY_PER_WINDOW,
17
+ DEFAULT_DECAY_WINDOW_MS,
18
+ DEFAULT_REINFORCE_DELTA,
19
+ decayEdgeConfidence,
20
+ readEdgeConfidence,
21
+ readLastReinforcedAt,
22
+ reinforceEdge
23
+ };
24
+ //# sourceMappingURL=graph-edge-reinforcement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,87 @@
1
+ import { EventEmitter } from 'node:events';
2
+
3
+ /**
4
+ * In-process EventEmitter for graph mutation events (issue #691 PR 5/5).
5
+ *
6
+ * The singleton is keyed by memoryDir so multiple orchestrator instances in
7
+ * the same process get distinct event buses (CLAUDE.md rule 11: scope globals
8
+ * per service). The SSE handler in access-http.ts subscribes to the bus for
9
+ * the resolved namespace and fans out to connected clients.
10
+ *
11
+ * Event types mirror the five mutations the graph layer can produce:
12
+ * node-added — a memory file was referenced for the first time
13
+ * node-updated — a memory file's metadata changed
14
+ * edge-added — a new edge was appended
15
+ * edge-updated — an existing edge's confidence/weight was modified
16
+ * edge-removed — an edge was pruned (e.g. by decay maintenance)
17
+ *
18
+ * The `GraphEventBus` interface is intentionally narrow so nothing outside
19
+ * this module needs to import Node.js EventEmitter directly.
20
+ */
21
+
22
+ type GraphEventType = "node-added" | "node-updated" | "edge-added" | "edge-updated" | "edge-removed";
23
+ interface GraphEvent {
24
+ type: GraphEventType;
25
+ /** Memory dir that owns this event (absolute path). */
26
+ memoryDir: string;
27
+ /** ISO timestamp of the event. */
28
+ ts: string;
29
+ /** Payload depends on event type — always serialisable to JSON. */
30
+ payload: Record<string, unknown>;
31
+ }
32
+ interface NodeAddedPayload {
33
+ nodeId: string;
34
+ kind: string;
35
+ label: string;
36
+ lastUpdated: string;
37
+ }
38
+ interface NodeUpdatedPayload {
39
+ nodeId: string;
40
+ kind: string;
41
+ label: string;
42
+ lastUpdated: string;
43
+ }
44
+ interface EdgeAddedPayload {
45
+ source: string;
46
+ target: string;
47
+ kind: string;
48
+ weight: number;
49
+ label: string;
50
+ confidence: number;
51
+ }
52
+ interface EdgeUpdatedPayload {
53
+ source: string;
54
+ target: string;
55
+ kind: string;
56
+ weight: number;
57
+ confidence: number;
58
+ }
59
+ interface EdgeRemovedPayload {
60
+ source: string;
61
+ target: string;
62
+ kind: string;
63
+ }
64
+ /**
65
+ * Return (or lazily create) the event bus for the given memoryDir.
66
+ * The same bus is shared by the write side (graph.ts → appendEdge hooks) and
67
+ * the read side (EngramAccessHttpServer SSE handler).
68
+ */
69
+ declare function getGraphEventBus(memoryDir: string): EventEmitter;
70
+ /**
71
+ * Emit a single graph event onto the bus for memoryDir.
72
+ * Fails open: any listener that throws is caught so one bad client can't
73
+ * crash the extraction pipeline.
74
+ */
75
+ declare function emitGraphEvent(memoryDir: string, type: GraphEventType, payload: Record<string, unknown>): void;
76
+ /**
77
+ * Subscribe to graph events for a given memoryDir.
78
+ * Returns an unsubscribe function.
79
+ */
80
+ declare function subscribeGraphEvents(memoryDir: string, listener: (event: GraphEvent) => void): () => void;
81
+ /**
82
+ * Remove all listeners and the bus entry for a memoryDir.
83
+ * Useful for tests that spin up isolated memory dirs.
84
+ */
85
+ declare function destroyGraphEventBus(memoryDir: string): void;
86
+
87
+ export { type EdgeAddedPayload, type EdgeRemovedPayload, type EdgeUpdatedPayload, type GraphEvent, type GraphEventType, type NodeAddedPayload, type NodeUpdatedPayload, destroyGraphEventBus, emitGraphEvent, getGraphEventBus, subscribeGraphEvents };