@remnic/core 9.3.684 → 9.3.685

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 (297) hide show
  1. package/dist/access-boundary.d.ts +3 -2
  2. package/dist/access-boundary.js +23 -23
  3. package/dist/access-cli.js +67 -67
  4. package/dist/access-http.d.ts +3 -2
  5. package/dist/access-http.js +26 -26
  6. package/dist/access-mcp.d.ts +3 -2
  7. package/dist/access-mcp.js +25 -25
  8. package/dist/access-operations.d.ts +3 -2
  9. package/dist/access-operations.js +24 -24
  10. package/dist/{access-service-D-siI-xJ.d.ts → access-service-DeKrlYU_.d.ts} +1 -10
  11. package/dist/access-service.d.ts +3 -2
  12. package/dist/access-service.js +22 -22
  13. package/dist/access-surface-catalog.d.ts +3 -2
  14. package/dist/active-recall.js +2 -2
  15. package/dist/{auto-sync-5CJBJMPZ.js → auto-sync-NUQWSFQD.js} +7 -7
  16. package/dist/bootstrap.d.ts +2 -1
  17. package/dist/bootstrap.js +2 -2
  18. package/dist/boxes.js +2 -2
  19. package/dist/briefing.js +3 -3
  20. package/dist/buffer.js +2 -2
  21. package/dist/calibration.js +4 -4
  22. package/dist/catalog-COqWZlZ6.d.ts +456 -0
  23. package/dist/causal-behavior.js +4 -4
  24. package/dist/causal-chain.js +4 -4
  25. package/dist/causal-consolidation.js +11 -11
  26. package/dist/causal-retrieval.js +4 -4
  27. package/dist/causal-trajectory-graph.js +1 -1
  28. package/dist/causal-trajectory.js +1 -1
  29. package/dist/{chunk-ROHLEUTH.js → chunk-2KAYTPPT.js} +10 -10
  30. package/dist/{chunk-NHQGDVJF.js → chunk-2SJCWLQD.js} +3 -3
  31. package/dist/{chunk-YTWNKQ2G.js → chunk-3FC6LW6T.js} +2 -2
  32. package/dist/{chunk-XEA4Z7JU.js → chunk-4FE2K57M.js} +3 -3
  33. package/dist/{chunk-WI7JKV2T.js → chunk-4N3TFFPH.js} +2 -2
  34. package/dist/{chunk-BTVX7ZXZ.js → chunk-4NFVPDIL.js} +4 -4
  35. package/dist/{chunk-OUWAQVDJ.js → chunk-5CEJH5ZN.js} +2 -2
  36. package/dist/{chunk-6QM24CP7.js → chunk-6GJS4BFH.js} +2 -2
  37. package/dist/{chunk-J2FBJ63F.js → chunk-6O6A6YUO.js} +4 -4
  38. package/dist/{chunk-HQ6NIBL6.js → chunk-7FL4CNPV.js} +2 -2
  39. package/dist/{chunk-5VDJMYTF.js → chunk-7WWURLG6.js} +3 -3
  40. package/dist/{chunk-QWRC7GIO.js → chunk-A4HH2EWA.js} +5 -5
  41. package/dist/{chunk-4SKKVWLQ.js → chunk-AGJH5ISO.js} +2 -2
  42. package/dist/{chunk-2L3KLWOV.js → chunk-B43NZNMG.js} +54 -92
  43. package/dist/chunk-B43NZNMG.js.map +1 -0
  44. package/dist/{chunk-WRE3JPAW.js → chunk-B4XVLHJA.js} +3 -3
  45. package/dist/{chunk-53FDU4CE.js → chunk-BLIWOONZ.js} +39 -36
  46. package/dist/chunk-BLIWOONZ.js.map +1 -0
  47. package/dist/{chunk-AJU4PJGY.js → chunk-BVKCV2ZY.js} +2 -2
  48. package/dist/{chunk-5N5DXYDW.js → chunk-BZISAF67.js} +7 -8
  49. package/dist/chunk-BZISAF67.js.map +1 -0
  50. package/dist/{chunk-DQY7NJ5L.js → chunk-CTOQEZSN.js} +2 -2
  51. package/dist/{chunk-7OGJQP7T.js → chunk-DCWIQFNA.js} +4 -4
  52. package/dist/{chunk-MHQC2WU2.js → chunk-DKTSR7EK.js} +2 -2
  53. package/dist/{chunk-RN7MUWON.js → chunk-EHISUJFN.js} +2 -2
  54. package/dist/{chunk-WLEB7WCG.js → chunk-EO5QWINU.js} +2 -2
  55. package/dist/{chunk-XKXKSQU7.js → chunk-EXM3CQTZ.js} +2 -2
  56. package/dist/{chunk-M3FWYURP.js → chunk-FE6DQUNJ.js} +9 -9
  57. package/dist/{chunk-LCC5EZTT.js → chunk-FIVDN2SM.js} +4 -4
  58. package/dist/{chunk-452WDNFO.js → chunk-GG6AJN7A.js} +2 -2
  59. package/dist/{chunk-2IBGHRIO.js → chunk-GS55WYRL.js} +3 -3
  60. package/dist/{chunk-IBTZEBUD.js → chunk-HYNHLBKA.js} +2 -2
  61. package/dist/{chunk-3EVIMVQU.js → chunk-IIDSFFE5.js} +2 -2
  62. package/dist/{chunk-EVWIEEKZ.js → chunk-IQ7WCZRW.js} +2 -2
  63. package/dist/{chunk-B5XMS73R.js → chunk-IQVQJJL7.js} +2 -2
  64. package/dist/{chunk-OXNOINIP.js → chunk-JPCKLFWK.js} +22 -23
  65. package/dist/{chunk-OXNOINIP.js.map → chunk-JPCKLFWK.js.map} +1 -1
  66. package/dist/{chunk-6RHNCKHG.js → chunk-K43PI6DQ.js} +2 -2
  67. package/dist/{chunk-OIF36KGD.js → chunk-KCQA46NR.js} +2 -2
  68. package/dist/{chunk-2LDBXPLB.js → chunk-KF74X62T.js} +1 -1
  69. package/dist/{chunk-MAV46GWQ.js → chunk-KYYL4U6X.js} +2 -2
  70. package/dist/{chunk-6GC5SGFE.js → chunk-L24JROPR.js} +2 -2
  71. package/dist/{chunk-Q5ZU3RNY.js → chunk-LQ6JI4VH.js} +2 -2
  72. package/dist/{chunk-GWKCEM3S.js → chunk-MCQDSY4G.js} +3 -3
  73. package/dist/{chunk-HP5FMB6L.js → chunk-MDJURR27.js} +2 -2
  74. package/dist/{chunk-2ODBA7MQ.js → chunk-NU3CSQ4H.js} +5 -5
  75. package/dist/chunk-NU3CSQ4H.js.map +1 -0
  76. package/dist/{chunk-T2PO5MUF.js → chunk-O7GOFAM3.js} +2 -2
  77. package/dist/{chunk-Z2OXSMZK.js → chunk-OBXTMFZQ.js} +3 -3
  78. package/dist/{chunk-5OE4PYY5.js → chunk-OFUULUSY.js} +8 -9
  79. package/dist/{chunk-5OE4PYY5.js.map → chunk-OFUULUSY.js.map} +1 -1
  80. package/dist/{chunk-K6ZN34WC.js → chunk-OV4D5T7V.js} +3 -3
  81. package/dist/{chunk-OMLIFZ4I.js → chunk-PH3HOKYW.js} +2 -2
  82. package/dist/{chunk-FYEVFGJD.js → chunk-PK6RGRSD.js} +2 -2
  83. package/dist/{chunk-C3IW2F5Z.js → chunk-PLBIPT6I.js} +2 -2
  84. package/dist/{chunk-QY7YA7OL.js → chunk-PNLCEFE4.js} +2 -2
  85. package/dist/{chunk-AGRPGAKR.js → chunk-PONNZ54D.js} +2 -2
  86. package/dist/{chunk-XZ4WBBB5.js → chunk-PWFWCGOO.js} +2 -2
  87. package/dist/{chunk-XWEXT4XU.js → chunk-QANVLERJ.js} +4 -4
  88. package/dist/{chunk-W4RVMTHR.js → chunk-QRDOSYOR.js} +2 -2
  89. package/dist/{chunk-6IMKOIZ6.js → chunk-R6OVFAX6.js} +2 -2
  90. package/dist/{chunk-JOASJWQR.js → chunk-SANZHXY2.js} +2 -2
  91. package/dist/{chunk-7DTASS5T.js → chunk-SJHM6I4J.js} +2 -2
  92. package/dist/{chunk-3MY4W5V4.js → chunk-SQGPGC76.js} +11 -21
  93. package/dist/{chunk-3MY4W5V4.js.map → chunk-SQGPGC76.js.map} +1 -1
  94. package/dist/{chunk-M6BVYHBU.js → chunk-STOEE37X.js} +4 -4
  95. package/dist/{chunk-GKKAXVAJ.js → chunk-U33LWTQQ.js} +1 -7
  96. package/dist/chunk-U33LWTQQ.js.map +1 -0
  97. package/dist/{chunk-LXH3DIF2.js → chunk-U7D7NP4J.js} +2 -2
  98. package/dist/{chunk-DRD2Q7HQ.js → chunk-UFS7OXGL.js} +2 -2
  99. package/dist/{chunk-H3HDXD3U.js → chunk-UPTZYUYJ.js} +2 -2
  100. package/dist/{chunk-3Z7NPD5T.js → chunk-UTYBJR7M.js} +2 -2
  101. package/dist/{chunk-LN4YGHTM.js → chunk-UUH4YQOF.js} +2 -2
  102. package/dist/{chunk-6VF75M3X.js → chunk-VGUOEDTU.js} +2 -2
  103. package/dist/{chunk-44VFF3BB.js → chunk-VILEUJXC.js} +2 -2
  104. package/dist/{chunk-7SI52C65.js → chunk-VL7DP3OW.js} +2 -2
  105. package/dist/{chunk-7DHTMOND.js → chunk-VQ34TERH.js} +2 -2
  106. package/dist/{chunk-6VMIHVGO.js → chunk-VX6OBUDW.js} +2 -2
  107. package/dist/{chunk-EW5KFXHL.js → chunk-WDXCNJSF.js} +7 -7
  108. package/dist/{chunk-FMEKEF47.js → chunk-WIHPNY65.js} +79 -3
  109. package/dist/chunk-WIHPNY65.js.map +1 -0
  110. package/dist/{chunk-X6IRLNOO.js → chunk-WIWPSQYU.js} +2 -2
  111. package/dist/{chunk-DOCTITOP.js → chunk-WRFKZEO6.js} +2 -2
  112. package/dist/{chunk-E6ZDCOHM.js → chunk-XBZQRZ6G.js} +2 -2
  113. package/dist/{chunk-7YX23JBA.js → chunk-XHYGJVXL.js} +2 -2
  114. package/dist/{chunk-JD4SCARD.js → chunk-YN4ZT4CW.js} +1 -1
  115. package/dist/{chunk-YXWAILM4.js → chunk-YOI3ELXF.js} +2 -2
  116. package/dist/{chunk-XCAZF7KQ.js → chunk-ZA2S2VLL.js} +2 -2
  117. package/dist/{chunk-BEUDU7Y4.js → chunk-ZCWIH4LH.js} +2 -2
  118. package/dist/{chunk-V25ZAOSB.js → chunk-ZPTISBQU.js} +5 -5
  119. package/dist/{cli-ooj6JQBS.d.ts → cli-D3-Q5Uod.d.ts} +2 -2
  120. package/dist/cli.d.ts +4 -3
  121. package/dist/cli.js +44 -44
  122. package/dist/compounding/engine.js +4 -4
  123. package/dist/compounding/preference-consolidator.js +1 -1
  124. package/dist/config.js +2 -2
  125. package/dist/connectors/codex-materialize-runner.js +4 -4
  126. package/dist/connectors/codex-materialize.js +2 -2
  127. package/dist/connectors/index.js +5 -5
  128. package/dist/contradiction/index.js +3 -3
  129. package/dist/{contradiction-scan-AZTGFMPY.js → contradiction-scan-HWGEOUDS.js} +3 -3
  130. package/dist/conversation-index/backend.js +5 -5
  131. package/dist/conversation-index/cleanup.js +2 -2
  132. package/dist/conversation-index/faiss-adapter.js +2 -2
  133. package/dist/conversation-index/indexer.js +2 -2
  134. package/dist/conversation-index/search.js +2 -2
  135. package/dist/day-summary.js +2 -2
  136. package/dist/embedding-fallback.js +2 -2
  137. package/dist/entity-retrieval.js +4 -4
  138. package/dist/explicit-capture.d.ts +2 -1
  139. package/dist/explicit-capture.js +1 -1
  140. package/dist/extraction-judge-telemetry.js +2 -2
  141. package/dist/extraction-judge-training.js +2 -2
  142. package/dist/extraction-judge.js +5 -5
  143. package/dist/extraction.js +9 -9
  144. package/dist/fallback-llm.js +4 -4
  145. package/dist/{graph-edge-decay-KSVJGCZW.js → graph-edge-decay-D7OESCBR.js} +2 -2
  146. package/dist/graph-snapshot.js +2 -2
  147. package/dist/graph.js +1 -1
  148. package/dist/index.d.ts +5 -4
  149. package/dist/index.js +80 -80
  150. package/dist/lcm/archive.js +2 -2
  151. package/dist/lcm/engine.js +5 -5
  152. package/dist/lcm/index.js +5 -5
  153. package/dist/lcm/schema.js +2 -2
  154. package/dist/lcm/summarizer.js +3 -3
  155. package/dist/local-llm.js +2 -2
  156. package/dist/logger.js +1 -1
  157. package/dist/maintenance/memory-governance.js +3 -3
  158. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
  159. package/dist/maintenance/rebuild-memory-projection.js +5 -5
  160. package/dist/mcp-memory-inspector-app.d.ts +3 -2
  161. package/dist/model-registry.js +2 -2
  162. package/dist/models-json.js +2 -2
  163. package/dist/namespaces/migrate.d.ts +1 -0
  164. package/dist/namespaces/migrate.js +16 -16
  165. package/dist/namespaces/search.js +13 -13
  166. package/dist/namespaces/storage.d.ts +42 -1
  167. package/dist/namespaces/storage.js +3 -3
  168. package/dist/native-knowledge.js +2 -2
  169. package/dist/negative.js +2 -2
  170. package/dist/operator-toolkit.js +22 -22
  171. package/dist/{orchestrator-DIDDvwDw.d.ts → orchestrator-CA6ouzBn.d.ts} +3 -464
  172. package/dist/orchestrator.d.ts +2 -1
  173. package/dist/orchestrator.js +61 -61
  174. package/dist/profiling.js +2 -2
  175. package/dist/qmd.js +2 -2
  176. package/dist/recall-planner-llm.js +4 -4
  177. package/dist/recall-qos.js +2 -2
  178. package/dist/recall-state.js +2 -2
  179. package/dist/relevance.js +2 -2
  180. package/dist/{resolution-IDTEBJFS.js → resolution-MN36NW5P.js} +3 -3
  181. package/dist/resolve-provider-secret.js +2 -2
  182. package/dist/resume-bundles.js +4 -4
  183. package/dist/retrieval-agents.js +2 -2
  184. package/dist/routing/store.js +2 -2
  185. package/dist/search/embed-helper.js +2 -2
  186. package/dist/search/factory.js +12 -12
  187. package/dist/search/index.js +12 -12
  188. package/dist/search/lancedb-backend.js +2 -2
  189. package/dist/search/meilisearch-backend.js +2 -2
  190. package/dist/search/orama-backend.js +2 -2
  191. package/dist/search/remote-backend.js +2 -2
  192. package/dist/semantic-consolidation.js +5 -5
  193. package/dist/semantic-rule-promotion.js +3 -3
  194. package/dist/semantic-rule-verifier.js +3 -3
  195. package/dist/session-observer-state.js +2 -2
  196. package/dist/session-transcript-migration.js +2 -2
  197. package/dist/shared-context/manager.js +2 -2
  198. package/dist/storage.d.ts +4 -0
  199. package/dist/storage.js +2 -2
  200. package/dist/summarizer.js +7 -7
  201. package/dist/temporal-supersession.js +2 -2
  202. package/dist/threading.js +2 -2
  203. package/dist/transcript.js +2 -2
  204. package/dist/verified-recall.js +4 -4
  205. package/package.json +2 -2
  206. package/src/access-http.ts +1 -1
  207. package/src/access-mcp.ts +1 -1
  208. package/src/access-service.ts +1 -11
  209. package/src/cli.ts +1 -1
  210. package/src/explicit-capture.ts +3 -12
  211. package/src/logger.ts +13 -4
  212. package/src/namespaces/catalog.test.ts +2 -2
  213. package/src/namespaces/storage.ts +81 -0
  214. package/src/orchestrator.ts +22 -64
  215. package/src/storage.ts +36 -36
  216. package/dist/chunk-2L3KLWOV.js.map +0 -1
  217. package/dist/chunk-2ODBA7MQ.js.map +0 -1
  218. package/dist/chunk-53FDU4CE.js.map +0 -1
  219. package/dist/chunk-5N5DXYDW.js.map +0 -1
  220. package/dist/chunk-FMEKEF47.js.map +0 -1
  221. package/dist/chunk-GKKAXVAJ.js.map +0 -1
  222. /package/dist/{auto-sync-5CJBJMPZ.js.map → auto-sync-NUQWSFQD.js.map} +0 -0
  223. /package/dist/{chunk-ROHLEUTH.js.map → chunk-2KAYTPPT.js.map} +0 -0
  224. /package/dist/{chunk-NHQGDVJF.js.map → chunk-2SJCWLQD.js.map} +0 -0
  225. /package/dist/{chunk-YTWNKQ2G.js.map → chunk-3FC6LW6T.js.map} +0 -0
  226. /package/dist/{chunk-XEA4Z7JU.js.map → chunk-4FE2K57M.js.map} +0 -0
  227. /package/dist/{chunk-WI7JKV2T.js.map → chunk-4N3TFFPH.js.map} +0 -0
  228. /package/dist/{chunk-BTVX7ZXZ.js.map → chunk-4NFVPDIL.js.map} +0 -0
  229. /package/dist/{chunk-OUWAQVDJ.js.map → chunk-5CEJH5ZN.js.map} +0 -0
  230. /package/dist/{chunk-6QM24CP7.js.map → chunk-6GJS4BFH.js.map} +0 -0
  231. /package/dist/{chunk-J2FBJ63F.js.map → chunk-6O6A6YUO.js.map} +0 -0
  232. /package/dist/{chunk-HQ6NIBL6.js.map → chunk-7FL4CNPV.js.map} +0 -0
  233. /package/dist/{chunk-5VDJMYTF.js.map → chunk-7WWURLG6.js.map} +0 -0
  234. /package/dist/{chunk-QWRC7GIO.js.map → chunk-A4HH2EWA.js.map} +0 -0
  235. /package/dist/{chunk-4SKKVWLQ.js.map → chunk-AGJH5ISO.js.map} +0 -0
  236. /package/dist/{chunk-WRE3JPAW.js.map → chunk-B4XVLHJA.js.map} +0 -0
  237. /package/dist/{chunk-AJU4PJGY.js.map → chunk-BVKCV2ZY.js.map} +0 -0
  238. /package/dist/{chunk-DQY7NJ5L.js.map → chunk-CTOQEZSN.js.map} +0 -0
  239. /package/dist/{chunk-7OGJQP7T.js.map → chunk-DCWIQFNA.js.map} +0 -0
  240. /package/dist/{chunk-MHQC2WU2.js.map → chunk-DKTSR7EK.js.map} +0 -0
  241. /package/dist/{chunk-RN7MUWON.js.map → chunk-EHISUJFN.js.map} +0 -0
  242. /package/dist/{chunk-WLEB7WCG.js.map → chunk-EO5QWINU.js.map} +0 -0
  243. /package/dist/{chunk-XKXKSQU7.js.map → chunk-EXM3CQTZ.js.map} +0 -0
  244. /package/dist/{chunk-M3FWYURP.js.map → chunk-FE6DQUNJ.js.map} +0 -0
  245. /package/dist/{chunk-LCC5EZTT.js.map → chunk-FIVDN2SM.js.map} +0 -0
  246. /package/dist/{chunk-452WDNFO.js.map → chunk-GG6AJN7A.js.map} +0 -0
  247. /package/dist/{chunk-2IBGHRIO.js.map → chunk-GS55WYRL.js.map} +0 -0
  248. /package/dist/{chunk-IBTZEBUD.js.map → chunk-HYNHLBKA.js.map} +0 -0
  249. /package/dist/{chunk-3EVIMVQU.js.map → chunk-IIDSFFE5.js.map} +0 -0
  250. /package/dist/{chunk-EVWIEEKZ.js.map → chunk-IQ7WCZRW.js.map} +0 -0
  251. /package/dist/{chunk-B5XMS73R.js.map → chunk-IQVQJJL7.js.map} +0 -0
  252. /package/dist/{chunk-6RHNCKHG.js.map → chunk-K43PI6DQ.js.map} +0 -0
  253. /package/dist/{chunk-OIF36KGD.js.map → chunk-KCQA46NR.js.map} +0 -0
  254. /package/dist/{chunk-2LDBXPLB.js.map → chunk-KF74X62T.js.map} +0 -0
  255. /package/dist/{chunk-MAV46GWQ.js.map → chunk-KYYL4U6X.js.map} +0 -0
  256. /package/dist/{chunk-6GC5SGFE.js.map → chunk-L24JROPR.js.map} +0 -0
  257. /package/dist/{chunk-Q5ZU3RNY.js.map → chunk-LQ6JI4VH.js.map} +0 -0
  258. /package/dist/{chunk-GWKCEM3S.js.map → chunk-MCQDSY4G.js.map} +0 -0
  259. /package/dist/{chunk-HP5FMB6L.js.map → chunk-MDJURR27.js.map} +0 -0
  260. /package/dist/{chunk-T2PO5MUF.js.map → chunk-O7GOFAM3.js.map} +0 -0
  261. /package/dist/{chunk-Z2OXSMZK.js.map → chunk-OBXTMFZQ.js.map} +0 -0
  262. /package/dist/{chunk-K6ZN34WC.js.map → chunk-OV4D5T7V.js.map} +0 -0
  263. /package/dist/{chunk-OMLIFZ4I.js.map → chunk-PH3HOKYW.js.map} +0 -0
  264. /package/dist/{chunk-FYEVFGJD.js.map → chunk-PK6RGRSD.js.map} +0 -0
  265. /package/dist/{chunk-C3IW2F5Z.js.map → chunk-PLBIPT6I.js.map} +0 -0
  266. /package/dist/{chunk-QY7YA7OL.js.map → chunk-PNLCEFE4.js.map} +0 -0
  267. /package/dist/{chunk-AGRPGAKR.js.map → chunk-PONNZ54D.js.map} +0 -0
  268. /package/dist/{chunk-XZ4WBBB5.js.map → chunk-PWFWCGOO.js.map} +0 -0
  269. /package/dist/{chunk-XWEXT4XU.js.map → chunk-QANVLERJ.js.map} +0 -0
  270. /package/dist/{chunk-W4RVMTHR.js.map → chunk-QRDOSYOR.js.map} +0 -0
  271. /package/dist/{chunk-6IMKOIZ6.js.map → chunk-R6OVFAX6.js.map} +0 -0
  272. /package/dist/{chunk-JOASJWQR.js.map → chunk-SANZHXY2.js.map} +0 -0
  273. /package/dist/{chunk-7DTASS5T.js.map → chunk-SJHM6I4J.js.map} +0 -0
  274. /package/dist/{chunk-M6BVYHBU.js.map → chunk-STOEE37X.js.map} +0 -0
  275. /package/dist/{chunk-LXH3DIF2.js.map → chunk-U7D7NP4J.js.map} +0 -0
  276. /package/dist/{chunk-DRD2Q7HQ.js.map → chunk-UFS7OXGL.js.map} +0 -0
  277. /package/dist/{chunk-H3HDXD3U.js.map → chunk-UPTZYUYJ.js.map} +0 -0
  278. /package/dist/{chunk-3Z7NPD5T.js.map → chunk-UTYBJR7M.js.map} +0 -0
  279. /package/dist/{chunk-LN4YGHTM.js.map → chunk-UUH4YQOF.js.map} +0 -0
  280. /package/dist/{chunk-6VF75M3X.js.map → chunk-VGUOEDTU.js.map} +0 -0
  281. /package/dist/{chunk-44VFF3BB.js.map → chunk-VILEUJXC.js.map} +0 -0
  282. /package/dist/{chunk-7SI52C65.js.map → chunk-VL7DP3OW.js.map} +0 -0
  283. /package/dist/{chunk-7DHTMOND.js.map → chunk-VQ34TERH.js.map} +0 -0
  284. /package/dist/{chunk-6VMIHVGO.js.map → chunk-VX6OBUDW.js.map} +0 -0
  285. /package/dist/{chunk-EW5KFXHL.js.map → chunk-WDXCNJSF.js.map} +0 -0
  286. /package/dist/{chunk-X6IRLNOO.js.map → chunk-WIWPSQYU.js.map} +0 -0
  287. /package/dist/{chunk-DOCTITOP.js.map → chunk-WRFKZEO6.js.map} +0 -0
  288. /package/dist/{chunk-E6ZDCOHM.js.map → chunk-XBZQRZ6G.js.map} +0 -0
  289. /package/dist/{chunk-7YX23JBA.js.map → chunk-XHYGJVXL.js.map} +0 -0
  290. /package/dist/{chunk-JD4SCARD.js.map → chunk-YN4ZT4CW.js.map} +0 -0
  291. /package/dist/{chunk-YXWAILM4.js.map → chunk-YOI3ELXF.js.map} +0 -0
  292. /package/dist/{chunk-XCAZF7KQ.js.map → chunk-ZA2S2VLL.js.map} +0 -0
  293. /package/dist/{chunk-BEUDU7Y4.js.map → chunk-ZCWIH4LH.js.map} +0 -0
  294. /package/dist/{chunk-V25ZAOSB.js.map → chunk-ZPTISBQU.js.map} +0 -0
  295. /package/dist/{contradiction-scan-AZTGFMPY.js.map → contradiction-scan-HWGEOUDS.js.map} +0 -0
  296. /package/dist/{graph-edge-decay-KSVJGCZW.js.map → graph-edge-decay-D7OESCBR.js.map} +0 -0
  297. /package/dist/{resolution-IDTEBJFS.js.map → resolution-MN36NW5P.js.map} +0 -0
@@ -2,10 +2,10 @@ import {
2
2
  SharedContextManager,
3
3
  SharedFeedbackEntrySchema,
4
4
  resolveSharedContextDir
5
- } from "../chunk-DRD2Q7HQ.js";
5
+ } from "../chunk-UFS7OXGL.js";
6
6
  import "../chunk-EYIEWJNI.js";
7
7
  import "../chunk-JUC24CTX.js";
8
- import "../chunk-2ODBA7MQ.js";
8
+ import "../chunk-NU3CSQ4H.js";
9
9
  import "../chunk-PZ5AY32C.js";
10
10
  export {
11
11
  SharedContextManager,
package/dist/storage.d.ts CHANGED
@@ -153,6 +153,9 @@ declare class StorageManager {
153
153
  private offlineSyncDigestCacheWriteTimer;
154
154
  /** Optional: set by the orchestrator after construction to enable template-aware citation stripping during legacy hash rebuild. */
155
155
  citationTemplate: string;
156
+ /** Post-write catalog hook (#1522). Installed by the namespace router; fire-and-forget. */
157
+ onCatalogWrite?: () => void;
158
+ private notifyCatalogWrite;
156
159
  /** Page-versioning configuration. Set by the orchestrator after construction. */
157
160
  private _versioningConfig;
158
161
  /** Set the page-versioning configuration. When `enabled` is false (default), all versioning calls are no-ops. */
@@ -296,6 +299,7 @@ declare class StorageManager {
296
299
  private resolveEntityFilePath;
297
300
  private readStorageSecureFile;
298
301
  private writeStorageSecureFile;
302
+ private writeStorageSecureFileChunks;
299
303
  private assertManagedStoragePath;
300
304
  readOfflineSyncFile(filePath: string): Promise<Buffer>;
301
305
  digestOfflineSyncFile(filePath: string): Promise<{
package/dist/storage.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  parseEntityFile,
10
10
  serializeEntityFile,
11
11
  stripAttributesSuffix
12
- } from "./chunk-53FDU4CE.js";
12
+ } from "./chunk-BLIWOONZ.js";
13
13
  import "./chunk-M7XQSUBB.js";
14
14
  import "./chunk-5UZXUTVO.js";
15
15
  import "./chunk-5GPPACXK.js";
@@ -33,7 +33,7 @@ import "./chunk-VS2IYZRU.js";
33
33
  import "./chunk-ZPQVJEVQ.js";
34
34
  import "./chunk-4DJQYKMN.js";
35
35
  import "./chunk-JUC24CTX.js";
36
- import "./chunk-2ODBA7MQ.js";
36
+ import "./chunk-NU3CSQ4H.js";
37
37
  import "./chunk-PZ5AY32C.js";
38
38
  export {
39
39
  ContentHashIndex,
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  HourlySummarizer
3
- } from "./chunk-QWRC7GIO.js";
3
+ } from "./chunk-A4HH2EWA.js";
4
4
  import "./chunk-XJNBEDFE.js";
5
- import "./chunk-XZ4WBBB5.js";
6
- import "./chunk-H3HDXD3U.js";
5
+ import "./chunk-PWFWCGOO.js";
6
+ import "./chunk-UPTZYUYJ.js";
7
7
  import "./chunk-S4DDLTPX.js";
8
- import "./chunk-LCC5EZTT.js";
9
- import "./chunk-B5XMS73R.js";
8
+ import "./chunk-FIVDN2SM.js";
9
+ import "./chunk-IQVQJJL7.js";
10
10
  import "./chunk-L2EXJQJP.js";
11
- import "./chunk-7SI52C65.js";
11
+ import "./chunk-VL7DP3OW.js";
12
12
  import "./chunk-RK6F44Y6.js";
13
13
  import "./chunk-FF4KLI5W.js";
14
14
  import "./chunk-O75CRYGF.js";
15
15
  import "./chunk-RGMVMVMF.js";
16
16
  import "./chunk-EYIEWJNI.js";
17
17
  import "./chunk-JUC24CTX.js";
18
- import "./chunk-2ODBA7MQ.js";
18
+ import "./chunk-NU3CSQ4H.js";
19
19
  import "./chunk-PZ5AY32C.js";
20
20
  export {
21
21
  HourlySummarizer
@@ -6,9 +6,9 @@ import {
6
6
  shouldFilterSupersededFromRecall,
7
7
  shouldSupersedeExisting,
8
8
  supersessionKeysForFact
9
- } from "./chunk-YTWNKQ2G.js";
9
+ } from "./chunk-3FC6LW6T.js";
10
10
  import "./chunk-MDYG7VI7.js";
11
- import "./chunk-2ODBA7MQ.js";
11
+ import "./chunk-NU3CSQ4H.js";
12
12
  import "./chunk-PZ5AY32C.js";
13
13
  export {
14
14
  applyTemporalSupersession,
package/dist/threading.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  ThreadingManager
3
- } from "./chunk-W4RVMTHR.js";
3
+ } from "./chunk-QRDOSYOR.js";
4
4
  import "./chunk-FF4KLI5W.js";
5
- import "./chunk-2ODBA7MQ.js";
5
+ import "./chunk-NU3CSQ4H.js";
6
6
  import "./chunk-PZ5AY32C.js";
7
7
  export {
8
8
  ThreadingManager
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  TranscriptManager,
3
3
  utcDayRange
4
- } from "./chunk-AGRPGAKR.js";
4
+ } from "./chunk-PONNZ54D.js";
5
5
  import "./chunk-S4DDLTPX.js";
6
6
  import "./chunk-KFY3SGN7.js";
7
7
  import "./chunk-FF4KLI5W.js";
8
- import "./chunk-2ODBA7MQ.js";
8
+ import "./chunk-NU3CSQ4H.js";
9
9
  import "./chunk-PZ5AY32C.js";
10
10
  export {
11
11
  TranscriptManager,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  compareVerifiedEpisodeResults,
3
3
  searchVerifiedEpisodes
4
- } from "./chunk-XEA4Z7JU.js";
5
- import "./chunk-HQ6NIBL6.js";
6
- import "./chunk-53FDU4CE.js";
4
+ } from "./chunk-4FE2K57M.js";
5
+ import "./chunk-7FL4CNPV.js";
6
+ import "./chunk-BLIWOONZ.js";
7
7
  import "./chunk-M7XQSUBB.js";
8
8
  import "./chunk-5UZXUTVO.js";
9
9
  import "./chunk-5GPPACXK.js";
@@ -27,7 +27,7 @@ import "./chunk-VS2IYZRU.js";
27
27
  import "./chunk-ZPQVJEVQ.js";
28
28
  import "./chunk-4DJQYKMN.js";
29
29
  import "./chunk-JUC24CTX.js";
30
- import "./chunk-2ODBA7MQ.js";
30
+ import "./chunk-NU3CSQ4H.js";
31
31
  import "./chunk-ZBJMUXZH.js";
32
32
  import "./chunk-PZ5AY32C.js";
33
33
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.3.684",
3
+ "version": "9.3.685",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2931,7 +2931,7 @@
2931
2931
  "core"
2932
2932
  ],
2933
2933
  "peerDependencies": {
2934
- "@remnic/coding-graph": "^9.3.684"
2934
+ "@remnic/coding-graph": "^9.3.685"
2935
2935
  },
2936
2936
  "peerDependenciesMeta": {
2937
2937
  "@remnic/coding-graph": {
@@ -1707,7 +1707,7 @@ export class EngramAccessHttpServer {
1707
1707
  // extraction write path. Record it so QMD maintenance / writtenSince
1708
1708
  // don't miss the write. Best-effort and failure-tolerant.
1709
1709
  onMergedMemoryWritten: (namespace, storageDir) => {
1710
- this.service.recordCatalogWrite(namespace, storageDir);
1710
+ // #1522: catalog touch handled at the storage chokepoint.
1711
1711
  },
1712
1712
  });
1713
1713
  this.respondJson(res, 200, result);
package/src/access-mcp.ts CHANGED
@@ -3231,7 +3231,7 @@ export class EngramMcpServer {
3231
3231
  // extraction write path. Record it so QMD maintenance / writtenSince
3232
3232
  // don't miss the write. Best-effort and failure-tolerant.
3233
3233
  onMergedMemoryWritten: (namespace, storageDir) => {
3234
- this.service.recordCatalogWrite(namespace, storageDir);
3234
+ // #1522: catalog touch handled at the storage chokepoint.
3235
3235
  },
3236
3236
  });
3237
3237
  }
@@ -7646,17 +7646,7 @@ export class EngramAccessService {
7646
7646
  return this.orchestrator.storage;
7647
7647
  }
7648
7648
 
7649
- /**
7650
- * Best-effort catalog write touch delegate (issue #1499 sweep). HTTP/MCP
7651
- * surfaces resolve a per-namespace storage and write through it directly (e.g.
7652
- * a contradiction merge), bypassing the extraction write path that owns
7653
- * `markCatalogWrite`. They call this to record the write so a (possibly
7654
- * dynamic) namespace's `lastWriteAt` stays accurate and QMD maintenance does
7655
- * not miss it. Fire-and-forget and failure-tolerant on the orchestrator side.
7656
- */
7657
- recordCatalogWrite(namespace?: string, storageDir?: string): void {
7658
- this.orchestrator.recordCatalogWrite(namespace, storageDir);
7659
- }
7649
+ // #1522: recordCatalogWrite removed — catalog touch handled at the storage chokepoint.
7660
7650
 
7661
7651
  get configRef(): PluginConfig {
7662
7652
  return this.orchestrator.config;
package/src/cli.ts CHANGED
@@ -8999,7 +8999,7 @@ export function registerCli(
8999
8999
  // bypassing the extraction write path. Record it so QMD maintenance /
9000
9000
  // writtenSince don't miss the write. Best-effort and failure-tolerant.
9001
9001
  onMergedMemoryWritten: (namespace, storageDir) => {
9002
- orchestrator.recordCatalogWrite(namespace, storageDir);
9002
+ // #1522: catalog touch handled at the storage chokepoint.
9003
9003
  },
9004
9004
  });
9005
9005
  console.log(result.message);
@@ -435,15 +435,8 @@ export async function persistExplicitCapture(
435
435
  expiresAt: candidate.expiresAt,
436
436
  source: source === "inline" ? "explicit-inline" : "explicit",
437
437
  });
438
- // Record the catalog write touch (issue #1499, round 5 codex P2). Explicit
439
- // captures bypass the extraction write path, so without this their namespace
440
- // never updates `lastWriteAt`. An undefined namespace means the DEFAULT root
441
- // (round 6, codex P2), which recordCatalogWrite resolves. The method is an
442
- // optional best-effort hook — guard so Orchestrator-like callers without it
443
- // don't break (rule #33). Best-effort and failure-tolerant.
444
- if (typeof orchestrator.recordCatalogWrite === "function") {
445
- orchestrator.recordCatalogWrite(resolvedNamespace, storage.dir);
446
- }
438
+ // #1522: catalog touch handled at the storage chokepoint the StorageManager's
439
+ // post-write hook records the namespace touch automatically.
447
440
 
448
441
  const created = new Date().toISOString();
449
442
  const event: MemoryLifecycleEvent = {
@@ -559,9 +552,7 @@ export async function queueExplicitCaptureForReview(
559
552
  // `writeMemory` returns an id. If the later pending-review frontmatter update
560
553
  // fails, the memory file is still durable and must not disappear from
561
554
  // writtenSince/maintenance scheduling. Guarded optional hook (rule #33).
562
- if (typeof orchestrator.recordCatalogWrite === "function") {
563
- orchestrator.recordCatalogWrite(queueNamespace, storage.dir);
564
- }
555
+ // #1522: catalog touch handled at the storage chokepoint.
565
556
  }
566
557
  const event: MemoryLifecycleEvent = {
567
558
  eventId: `mle-${randomUUID()}`,
package/src/logger.ts CHANGED
@@ -15,11 +15,20 @@ const NOOP_LOGGER: LoggerBackend = {
15
15
  let _backend: LoggerBackend = NOOP_LOGGER;
16
16
  let _debug = false;
17
17
 
18
+ // Late-bind console.* rather than capturing references at module import
19
+ // time. In production this is behaviour-identical to the pre-bound
20
+ // `.bind(console)` form — `console.info(msg, ...)` resolves `this` to
21
+ // `console` whether called directly or via an arrow wrapper — but it lets
22
+ // harnesses that swap console methods (e.g. runCli in @remnic/cli) route
23
+ // logger output through their capture sinks. With the old pre-bound form,
24
+ // any command that called initLogger() pinned the logger to the original
25
+ // console methods before the harness could swap them, so log.warn /
26
+ // log.info output escaped the capture buffer.
18
27
  const CONSOLE_LOGGER: LoggerBackend = {
19
- info: console.info.bind(console),
20
- warn: console.warn.bind(console),
21
- error: console.error.bind(console),
22
- debug: console.debug.bind(console),
28
+ info: (msg, ...args) => console.info(msg, ...args),
29
+ warn: (msg, ...args) => console.warn(msg, ...args),
30
+ error: (msg, ...args) => console.error(msg, ...args),
31
+ debug: (msg, ...args) => console.debug(msg, ...args),
23
32
  };
24
33
 
25
34
  export function initLogger(backend?: LoggerBackend, debug?: boolean): void {
@@ -539,7 +539,7 @@ test("register does not overwrite prior discoveredBy on an existing record", asy
539
539
 
540
540
  // A record first PRE-REGISTERED via the router's onResolve hook (config) is
541
541
  // UPGRADED to "write" by a later real write touch (round 6, codex P2 — NBPmT):
542
- // `storageFor()` fires registerResolved (config) before recordCatalogWrite runs,
542
+ // `storageFor()` fires registerResolved (config) before the storage chokepoint runs,
543
543
  // so without the upgrade `listNamespaces({ discoveredBy: "write" })` would miss a
544
544
  // genuinely-written namespace. A non-write touch (read/register) still preserves
545
545
  // provenance.
@@ -689,7 +689,7 @@ test("chunked write path contract: markWrite updates lastWriteAt for the namespa
689
689
  const ns = "project-origin-chunked";
690
690
  const storageDir = path.join(memoryDir, "namespaces", namespaceIdentityToken(ns));
691
691
  // This is exactly the call the orchestrator chunked branch now makes
692
- // (markCatalogWrite -> markWrite with discoveredBy "write" + storageDir).
692
+ // (storage chokepoint -> markWrite with discoveredBy "write" + storageDir).
693
693
  await catalog.markWrite(ns, { discoveredBy: "write", storageDir });
694
694
  const record = await catalog.getNamespaceRecord(ns);
695
695
  assert.ok(record?.lastWriteAt, "chunked write must update lastWriteAt");
@@ -5,6 +5,7 @@ import { StorageManager } from "../storage.js";
5
5
  import type { PluginConfig } from "../types.js";
6
6
  import { ALL_CATEGORY_DIRS } from "../utils/category-dir.js";
7
7
  import { namespaceIdentityToken, normalizeNamespaceIdentity } from "./identity.js";
8
+ import type { NamespaceCatalog } from "./catalog.js";
8
9
 
9
10
  async function exists(p: string): Promise<boolean> {
10
11
  try {
@@ -228,6 +229,9 @@ export class NamespaceStorageRouter {
228
229
  // `whenResolveHooksSettled`). Entries are removed as each hook settles, so the
229
230
  // set holds at most one promise per concurrently-resolving namespace.
230
231
  private readonly pendingResolveHooks = new Set<Promise<unknown>>();
232
+ // Pending post-write catalog touch promises (#1522). Like pendingResolveHooks,
233
+ // lets tests await fire-and-forget write touches deterministically.
234
+ private readonly pendingWriteTouches = new Set<Promise<unknown>>();
231
235
 
232
236
  // Normalized (trimmed) default namespace identity (NH-FH). `storageFor`
233
237
  // normalizes its input, so default-namespace branches must compare against the
@@ -238,6 +242,8 @@ export class NamespaceStorageRouter {
238
242
  constructor(
239
243
  private readonly config: PluginConfig,
240
244
  private readonly hooks: NamespaceStorageRouterHooks = {},
245
+ /** Catalog reference for post-write/read touches (issue #1522 chokepoint). */
246
+ private readonly catalog?: NamespaceCatalog,
241
247
  ) {
242
248
  this.defaultNamespaceIdentity = normalizeNamespaceIdentity(config.defaultNamespace);
243
249
  }
@@ -288,6 +294,9 @@ export class NamespaceStorageRouter {
288
294
  // (used by extraction and shared-promotion paths) strip citations consistently,
289
295
  // matching the behaviour of the primary this.storage instance in the orchestrator.
290
296
  sm.citationTemplate = this.config.inlineSourceAttributionFormat;
297
+ // #1522: install the post-write catalog touch at the chokepoint — every
298
+ // successful write on this StorageManager records the namespace touch.
299
+ this.bindCatalogWriteHook(sm, ns);
291
300
  this.cache.set(ns, sm);
292
301
  this.notifyResolved(ns, root);
293
302
  return sm;
@@ -369,6 +378,78 @@ export class NamespaceStorageRouter {
369
378
  }
370
379
  }
371
380
 
381
+ /**
382
+ * Install the post-write catalog touch hook on an externally-constructed
383
+ * StorageManager (issue #1522). Used by the orchestrator for the legacy
384
+ * default-namespace storage (`this.storage`) that bypasses the router.
385
+ */
386
+ bindCatalogWriteHook(sm: StorageManager, namespace: string): void {
387
+ sm.onCatalogWrite = () => this.touchCatalogWrite(namespace, sm.dir);
388
+ }
389
+
390
+ /**
391
+ * Post-write catalog touch (issue #1522 chokepoint). Called by every
392
+ * StorageManager's post-write hook AFTER a successful write. Best-effort
393
+ * and failure-tolerant — a catalog error MUST NOT affect the primary write
394
+ * (gotcha #13, rule #40). Fire-and-forget by design.
395
+ */
396
+ private touchCatalogWrite(namespace: string, storageDir: string): void {
397
+ if (!this.catalog) return;
398
+ const touch = this.catalog
399
+ .markWrite(namespace, { discoveredBy: "write", storageDir })
400
+ .catch(() => undefined);
401
+ this.pendingWriteTouches.add(touch);
402
+ void touch.then(
403
+ () => { this.pendingWriteTouches.delete(touch); },
404
+ () => { this.pendingWriteTouches.delete(touch); },
405
+ );
406
+ }
407
+
408
+ /**
409
+ * Record a namespace read in the catalog (issue #1522 chokepoint move).
410
+ * Best-effort and failure-tolerant. Used by recall paths so the read touch
411
+ * lives in the storage layer, not at the caller.
412
+ */
413
+ recordRead(namespace: string, storageDir?: string): void {
414
+ if (!this.catalog) return;
415
+ const ns = normalizeNamespaceIdentity(namespace || this.config.defaultNamespace);
416
+ void this.catalog
417
+ .markRead(ns, { discoveredBy: "read", storageDir })
418
+ .catch(() => undefined);
419
+ }
420
+ /**
421
+ * Record a namespace write touch in the catalog (issue #1522). Best-effort
422
+ * and failure-tolerant. Used by consolidation/cleanup passes that may mutate
423
+ * the store via delete-only paths (e.g. entity-file merges, TTL cleanup) so
424
+ * the namespace's lastWriteAt stays fresh even when no explicit write went
425
+ * through the storage chokepoint. This is NOT a substitute for the chokepoint
426
+ * — it's a belt-and-suspenders for paths the chokepoint doesn't cover.
427
+ */
428
+ recordWrite(namespace: string, storageDir?: string): void {
429
+ if (!this.catalog) return;
430
+ const ns = normalizeNamespaceIdentity(namespace || this.config.defaultNamespace);
431
+ const touch = this.catalog
432
+ .markWrite(ns, { discoveredBy: "write", storageDir })
433
+ .catch(() => undefined);
434
+ this.pendingWriteTouches.add(touch);
435
+ void touch.then(
436
+ () => { this.pendingWriteTouches.delete(touch); },
437
+ () => { this.pendingWriteTouches.delete(touch); },
438
+ );
439
+ }
440
+
441
+ /**
442
+ * Resolve once every in-flight post-write catalog touch has settled (#1522).
443
+ * Mirrors `whenResolveHooksSettled()`: the StorageManager's post-write hook
444
+ * fires the catalog touch fire-and-forget, so tests asserting lastWriteAt
445
+ * moved should await this instead of racing a timer.
446
+ */
447
+ async whenWriteTouchesSettled(): Promise<void> {
448
+ while (this.pendingWriteTouches.size > 0) {
449
+ await Promise.allSettled([...this.pendingWriteTouches]);
450
+ }
451
+ }
452
+
372
453
  /**
373
454
  * Resolve once every in-flight `onResolve` registration has settled.
374
455
  *
@@ -2682,7 +2682,7 @@ export class Orchestrator {
2682
2682
  this.rememberNamespaceStorageDirHint(namespace, storageDir);
2683
2683
  return this.namespaceCatalog.registerResolved(namespace, storageDir);
2684
2684
  },
2685
- });
2685
+ }, this.namespaceCatalog);
2686
2686
  this.namespaceSearchRouter = new NamespaceSearchRouter(
2687
2687
  config,
2688
2688
  this.storageRouter,
@@ -2691,6 +2691,8 @@ export class Orchestrator {
2691
2691
  // Propagate the inline-attribution template so the storage layer can strip
2692
2692
  // citations from legacy facts during the hash-index rebuild path.
2693
2693
  this.storage.citationTemplate = config.inlineSourceAttributionFormat;
2694
+ // #1522: bind the post-write catalog touch at the storage chokepoint.
2695
+ if (config.defaultNamespace) this.storageRouter.bindCatalogWriteHook(this.storage, config.defaultNamespace);
2694
2696
  // Wire page-level versioning (issue #371)
2695
2697
  this.storage.setVersioningConfig({
2696
2698
  enabled: config.versioningEnabled,
@@ -4479,11 +4481,7 @@ export class Orchestrator {
4479
4481
  // failures where the canonical memory was written but a later archive
4480
4482
  // step throws and the cluster catch continues (codex NY-dK).
4481
4483
  // Best-effort; namespace decoded from the storage dir since this path
4482
- // has no routed namespace name.
4483
- this.markCatalogWrite(
4484
- this.namespaceFromStorageDir(targetStorage.dir),
4485
- targetStorage.dir,
4486
- );
4484
+ // #1522: catalog touch handled at the storage chokepoint.
4487
4485
  }
4488
4486
  }
4489
4487
  }
@@ -7992,7 +7990,7 @@ export class Orchestrator {
7992
7990
  recallResultLimit > 0 &&
7993
7991
  !options.abortSignal?.aborted
7994
7992
  ) {
7995
- for (const ns of recallNamespaces) this.markCatalogRead(ns);
7993
+ for (const ns of recallNamespaces) this.storageRouter.recordRead(ns);
7996
7994
  }
7997
7995
 
7998
7996
  // 0. Shared context (v4.0, optional)
@@ -14200,7 +14198,6 @@ export class Orchestrator {
14200
14198
  );
14201
14199
  }
14202
14200
  }
14203
- this.markCatalogWrite(target.namespace, targetStorage.dir);
14204
14201
  trackPersistedId(targetStorage, promotedId, { includeReturnedIds: false });
14205
14202
  await this.indexPersistedMemory(targetStorage, promotedId);
14206
14203
  trackBehaviorSignals(
@@ -14391,17 +14388,16 @@ export class Orchestrator {
14391
14388
  useCallerTimestamp: true,
14392
14389
  });
14393
14390
  // Catalog touch (issue #1499 — codex P2 NElSf): this dedup branch
14394
- // returns WITHOUT reaching the post-write `markCatalogWrite` below,
14391
+ // returns WITHOUT the post-write catalog touch (now at the storage chokepoint #1522),
14395
14392
  // but `applyTemporalSupersession` mutated the shared namespace
14396
14393
  // (it rewrote frontmatter to retire stale shared facts). When any
14397
14394
  // ids were actually superseded, the shared namespace changed, so we
14398
14395
  // must record the write — otherwise the shared record's
14399
14396
  // `lastWriteAt` stays stale and `writtenSince` maintenance / QMD
14400
14397
  // fanout skips the namespace after a supersession-only update.
14401
- // Best-effort and failure-tolerant (markCatalogWrite swallows
14398
+ // Best-effort and failure-tolerant (the storage chokepoint swallows
14402
14399
  // errors); only touch when work happened to avoid spurious writes.
14403
14400
  if (hashDedupSupersession.supersededIds.length > 0) {
14404
- this.markCatalogWrite(this.config.sharedNamespace, sharedStorage.dir);
14405
14401
  }
14406
14402
  // Active matching fact exists — normal short-circuit is safe.
14407
14403
  return;
@@ -14505,7 +14501,6 @@ export class Orchestrator {
14505
14501
  // the same promotion pass. The hot-path source-namespace touch uses a
14506
14502
  // different storage dir, so this does not double-count the source.
14507
14503
  // Best-effort and failure-tolerant — it must never crash the promotion.
14508
- this.markCatalogWrite(this.config.sharedNamespace, sharedStorage.dir);
14509
14504
  trackPersistedId(sharedStorage, promotedId, {
14510
14505
  includeReturnedIds: false,
14511
14506
  });
@@ -15358,7 +15353,6 @@ export class Orchestrator {
15358
15353
  // failure still surfaces the partially durable parent/chunk files to
15359
15354
  // catalog-driven `writtenSince` maintenance. The final touch below
15360
15355
  // still refreshes `lastWriteAt` after later durable writes on success.
15361
- this.markCatalogWrite(targetNamespaceName, targetStorage.dir);
15362
15356
  }
15363
15357
 
15364
15358
  if (routedRuleId) {
@@ -15502,7 +15496,6 @@ export class Orchestrator {
15502
15496
  // promotion, optional artifact writes, and graph-edge writes — so
15503
15497
  // `lastWriteAt` cannot precede later file changes on successful
15504
15498
  // completion. Use the KNOWN routed name, not a dir-decoded guess.
15505
- this.markCatalogWrite(targetNamespaceName, targetStorage.dir);
15506
15499
  }
15507
15500
  trackBehaviorSignals(
15508
15501
  targetStorage,
@@ -15732,13 +15725,12 @@ export class Orchestrator {
15732
15725
  // The `finally` preserves the write touch when post-write indexing or
15733
15726
  // promotion fails after the canonical memory is already durable. Use the
15734
15727
  // KNOWN routed name, not a dir-decoded guess (NCQI0).
15735
- this.markCatalogWrite(targetNamespaceName, targetStorage.dir);
15736
15728
  }
15737
15729
  }
15738
15730
 
15739
15731
  // Tracks whether THIS extraction persisted any durable, non-fact output to the
15740
15732
  // BASE namespace's storage (entity / relationship / profile / question). The
15741
- // per-fact `markCatalogWrite` only fires inside the fact write loop, so a
15733
+ // per-fact catalog touch (storage chokepoint #1522) only fires inside the fact write loop, so a
15742
15734
  // fact-less extraction that still persists durable data must record exactly one
15743
15735
  // base-namespace catalog touch after all writes complete (NHZEZ, codex P2).
15744
15736
  let durableNonFactWritten = false;
@@ -15748,7 +15740,6 @@ export class Orchestrator {
15748
15740
  baseNamespace && baseNamespace.length > 0
15749
15741
  ? baseNamespace
15750
15742
  : this.namespaceFromStorageDir(storage.dir);
15751
- this.markCatalogWrite(baseTouchNamespace, storage.dir);
15752
15743
  };
15753
15744
  const recordDurableNonFactWrite = () => {
15754
15745
  durableNonFactWritten = true;
@@ -15863,7 +15854,7 @@ export class Orchestrator {
15863
15854
  }
15864
15855
 
15865
15856
  // Catalog touch for durable NON-FACT outputs (NHZEZ / NIIly, codex P2). The
15866
- // per-fact `markCatalogWrite` above only fires inside the fact write loop, so
15857
+ // per-fact catalog touch (storage chokepoint #1522) above only fires inside the fact write loop, so
15867
15858
  // an extraction that persists ONLY entities, relationships, profile updates,
15868
15859
  // questions, or an identity reflection (no facts) would record durable data to
15869
15860
  // the BASE namespace's storage without ever touching the catalog — leaving that
@@ -15874,7 +15865,7 @@ export class Orchestrator {
15874
15865
  // KNOWN base namespace name, not a dir-decoded guess (NCQI0). One touch per
15875
15866
  // namespace per extraction — `markWrite` is idempotent, so if the fact path
15876
15867
  // already touched the base namespace this only refreshes `lastWriteAt`.
15877
- // Best-effort and failure-tolerant (markCatalogWrite swallows errors).
15868
+ // Best-effort and failure-tolerant (storage chokepoint #1522 swallows errors).
15878
15869
  if (durableNonFactWritten) {
15879
15870
  touchBaseNonFactNamespace();
15880
15871
  }
@@ -16604,19 +16595,13 @@ export class Orchestrator {
16604
16595
  }
16605
16596
  }
16606
16597
 
16607
- // Consolidated catalog write touch (issue #1499 sweep; NIBOi + NIjwl). One
16608
- // touch covering EVERY durable namespace mutation this pass made LLM
16609
- // profile/entity/memory-item actions AND cleanup-only maintenance (entity-file
16610
- // merges, expired-commitment / ledger-lifecycle / TTL cleanup, fact archival).
16611
- // Recorded here, after all mutation-producing steps, so a cleanup-only run that
16612
- // rewrote the store still refreshes `lastWriteAt` (rule #25). The default
16613
- // namespace is always configured/cataloged; `markWrite` is idempotent so this
16614
- // only refreshes recency. Best-effort and failure-tolerant.
16598
+ // Consolidated catalog write touch belt-and-suspenders for cleanup-only
16599
+ // passes that mutate the store via delete-only paths (entity merges, TTL
16600
+ // cleanup) without triggering the storage chokepoint's post-write hook.
16601
+ // Gated on memoryItemMutated (set by every durable mutation including cleanup-only passes)
16602
+ // Best-effort and failure-tolerant.
16615
16603
  if (memoryItemMutated) {
16616
- this.markCatalogWrite(
16617
- this.namespaceFromStorageDir(this.storage.dir),
16618
- this.storage.dir,
16619
- );
16604
+ this.storageRouter.recordWrite(this.config.defaultNamespace, this.storage.dir);
16620
16605
  }
16621
16606
 
16622
16607
  log.info("consolidation complete");
@@ -17070,7 +17055,6 @@ export class Orchestrator {
17070
17055
  const lifecycleCorpus = await storage.readAllMemories();
17071
17056
  // Record the catalog write when the pass rewrote any frontmatter (codex NR-tS).
17072
17057
  if ((await this.runLifecyclePolicyPass(lifecycleCorpus, storage)) > 0) {
17073
- this.markCatalogWrite(this.namespaceFromStorageDir(storage.dir), storage.dir);
17074
17058
  }
17075
17059
  return { memoriesAssessed: lifecycleCorpus.length };
17076
17060
  }
@@ -17355,10 +17339,7 @@ export class Orchestrator {
17355
17339
  // summary and then rewrites source-memory archive status, bypassing the
17356
17340
  // extraction write path. Record the touch after both mutations complete so
17357
17341
  // `lastWriteAt` covers the final archived-state write.
17358
- this.markCatalogWrite(
17359
- this.namespaceFromStorageDir(this.storage.dir),
17360
- this.storage.dir,
17361
- );
17342
+ // #1522: catalog touch handled at the storage chokepoint.
17362
17343
 
17363
17344
  log.info(
17364
17345
  `created summary ${summary.id} from ${batch.length} memories, archived ${archived}`,
@@ -17469,11 +17450,10 @@ export class Orchestrator {
17469
17450
  // a namespace whose sole mutation in the pass is identity consolidation would
17470
17451
  // otherwise keep a stale `lastWriteAt`, making `listNamespaces({ writtenSince })`
17471
17452
  // and catalog-recency consumers miss the write. Best-effort and
17472
- // failure-tolerant (`markCatalogWrite` swallows errors, never crashing the
17453
+ // failure-tolerant (the storage chokepoint (#1522) swallows errors, never crashing the
17473
17454
  // consolidation; gotcha #13, rule #40). No double-count with the consolidated
17474
17455
  // touch above: that one is gated on `memoryItemMutated` (which identity
17475
17456
  // consolidation does not set), and `markWrite` is idempotent regardless.
17476
- this.markCatalogWrite(namespace, storage.dir);
17477
17457
  log.info(
17478
17458
  `IDENTITY(${namespace}) consolidated: ${identityContent.length} → ${newContent.length} chars, ${result.learnedPatterns.length} patterns`,
17479
17459
  );
@@ -19917,24 +19897,13 @@ export class Orchestrator {
19917
19897
  return dirName;
19918
19898
  }
19919
19899
 
19920
- /**
19921
- * Record a namespace write in the catalog (issue #1499). Best-effort and
19922
- * failure-tolerant: a catalog write error MUST NOT crash the primary memory
19923
- * write (CLAUDE.md gotcha #13, rule #40). Fire-and-forget by design.
19924
- */
19925
- private markCatalogWrite(namespace: string, storageDir?: string): void {
19926
- if (!this.namespaceCatalog.enabled) return;
19927
- this.rememberNamespaceStorageDirHint(namespace, storageDir);
19928
- void this.namespaceCatalog
19929
- .markWrite(namespace, { discoveredBy: "write", storageDir })
19930
- .catch(() => undefined);
19931
- }
19900
+ // #1522: catalog touch methods removed — touches now happen at the storage chokepoint.
19932
19901
 
19933
19902
  /**
19934
19903
  * Public best-effort catalog write touch (issue #1499). User-facing explicit
19935
19904
  * captures (`memory_store`) and review-queue approvals persist via
19936
19905
  * `persistExplicitCapture()` → `storage.writeMemory()`, which bypasses the
19937
- * extraction write path that calls `markCatalogWrite`. Without this their
19906
+ * extraction write path that owns the catalog touch. Without this their
19938
19907
  * namespaces never record `lastWriteAt`, so the catalog under-reports write
19939
19908
  * recency (round 5, codex P2). Fire-and-forget and failure-tolerant — a
19940
19909
  * catalog error must never affect the explicit write (gotcha #13, rule #40).
@@ -19944,20 +19913,9 @@ export class Orchestrator {
19944
19913
  * default rather than skipping it (round 6, codex P2 — default `memory_store`
19945
19914
  * and inline-note writes were missing from `writtenSince`/maintenance).
19946
19915
  */
19947
- recordCatalogWrite(namespace?: string, storageDir?: string): void {
19948
- const ns = namespace && namespace.trim().length > 0 ? namespace : this.config.defaultNamespace;
19949
- if (!ns) return;
19950
- this.markCatalogWrite(ns, storageDir);
19951
- }
19952
19916
 
19953
- /** Record a namespace read in the catalog. Best-effort, failure-tolerant. */
19954
- private markCatalogRead(namespace: string, storageDir?: string): void {
19955
- if (!this.namespaceCatalog.enabled) return;
19956
- this.rememberNamespaceStorageDirHint(namespace, storageDir);
19957
- void this.namespaceCatalog
19958
- .markRead(namespace, { discoveredBy: "read", storageDir })
19959
- .catch(() => undefined);
19960
- }
19917
+
19918
+ // markCatalogRead removed use storageRouter.recordRead() instead (#1522).
19961
19919
 
19962
19920
  private async readAllMemoriesForNamespaces(
19963
19921
  namespaces: string[],