@remnic/core 9.3.700 → 9.3.702

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/dist/access-boundary.d.ts +7 -7
  2. package/dist/access-boundary.js +17 -14
  3. package/dist/access-cli.js +40 -37
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +7 -7
  6. package/dist/access-http.js +20 -17
  7. package/dist/access-mcp.d.ts +7 -7
  8. package/dist/access-mcp.js +19 -16
  9. package/dist/access-operations.d.ts +7 -7
  10. package/dist/access-operations.js +18 -15
  11. package/dist/{access-service-Cte3ol0W.d.ts → access-service-COCzhgEL.d.ts} +397 -19
  12. package/dist/access-service.d.ts +6 -6
  13. package/dist/access-service.js +16 -13
  14. package/dist/access-surface-catalog.d.ts +7 -7
  15. package/dist/action-confidence.d.ts +1 -1
  16. package/dist/active-memory-bridge.d.ts +1 -1
  17. package/dist/active-memory-bridge.js +2 -2
  18. package/dist/active-recall.d.ts +1 -1
  19. package/dist/active-recall.js +7 -6
  20. package/dist/active-recall.js.map +1 -1
  21. package/dist/behavior-learner.d.ts +1 -1
  22. package/dist/behavior-signals.d.ts +1 -1
  23. package/dist/bootstrap.d.ts +5 -5
  24. package/dist/briefing.d.ts +1 -1
  25. package/dist/briefing.js +8 -7
  26. package/dist/buffer-surprise-report.d.ts +1 -1
  27. package/dist/buffer.d.ts +1 -1
  28. package/dist/calibration.d.ts +1 -1
  29. package/dist/capabilities.d.ts +1 -1
  30. package/dist/{catalog-DN1PzThs.d.ts → catalog-DxCzhjE6.d.ts} +28 -54
  31. package/dist/causal-behavior.d.ts +1 -1
  32. package/dist/causal-consolidation.d.ts +1 -1
  33. package/dist/causal-consolidation.js +9 -8
  34. package/dist/causal-consolidation.js.map +1 -1
  35. package/dist/{chunk-XJNBEDFE.js → chunk-3FAMU5TX.js} +31 -74
  36. package/dist/chunk-3FAMU5TX.js.map +1 -0
  37. package/dist/{chunk-PCZR32VL.js → chunk-3JJWNZTT.js} +2 -2
  38. package/dist/{chunk-YXLT4EMM.js → chunk-4463LUIE.js} +12 -2
  39. package/dist/chunk-4463LUIE.js.map +1 -0
  40. package/dist/{chunk-R5DB26G6.js → chunk-4SBW47WK.js} +9 -23
  41. package/dist/chunk-4SBW47WK.js.map +1 -0
  42. package/dist/{chunk-CCOXIDRM.js → chunk-5VXVXJH6.js} +149 -6
  43. package/dist/{chunk-CCOXIDRM.js.map → chunk-5VXVXJH6.js.map} +1 -1
  44. package/dist/{chunk-PQG4T5V3.js → chunk-64XXOQRW.js} +49 -45
  45. package/dist/chunk-64XXOQRW.js.map +1 -0
  46. package/dist/{chunk-YXIFA36P.js → chunk-6TAETM63.js} +2 -2
  47. package/dist/{chunk-6JDGADXK.js → chunk-6VVP6NK7.js} +2 -2
  48. package/dist/{chunk-FN2SM5SN.js → chunk-ABCGDW3A.js} +75 -12
  49. package/dist/chunk-ABCGDW3A.js.map +1 -0
  50. package/dist/{chunk-CHM274U6.js → chunk-AMNLZ6SF.js} +2 -2
  51. package/dist/{chunk-JX3YZVII.js → chunk-CZJ6QSKG.js} +3 -3
  52. package/dist/{chunk-GYVVQYA3.js → chunk-EOOVJK2U.js} +3 -3
  53. package/dist/{chunk-JKW5XSWC.js → chunk-EYJD6KIO.js} +2 -2
  54. package/dist/{chunk-XY4WJTEX.js → chunk-EZR35XHX.js} +2 -2
  55. package/dist/{chunk-UU6MVCJ6.js → chunk-FIOYURII.js} +32 -25
  56. package/dist/chunk-FIOYURII.js.map +1 -0
  57. package/dist/{chunk-2NWHLAXX.js → chunk-FVI5B7DE.js} +2 -2
  58. package/dist/{chunk-X74FJSW7.js → chunk-GFIARMA7.js} +16 -8
  59. package/dist/chunk-GFIARMA7.js.map +1 -0
  60. package/dist/{chunk-PONNZ54D.js → chunk-GY3SKOS4.js} +4 -4
  61. package/dist/{chunk-U33LWTQQ.js → chunk-HV57RHMD.js} +4 -4
  62. package/dist/{chunk-RC3CNIPK.js → chunk-IO5NQEGZ.js} +2 -2
  63. package/dist/{chunk-IKNQAGBV.js → chunk-IX3UQT4H.js} +1 -1
  64. package/dist/{chunk-IKNQAGBV.js.map → chunk-IX3UQT4H.js.map} +1 -1
  65. package/dist/{chunk-HDLC75NX.js → chunk-IX72AAMZ.js} +2 -2
  66. package/dist/{chunk-DR2JTSLZ.js → chunk-JMA4RYRN.js} +62 -163
  67. package/dist/chunk-JMA4RYRN.js.map +1 -0
  68. package/dist/{chunk-G5PKTQ5J.js → chunk-JTKFZMZ7.js} +2 -2
  69. package/dist/{chunk-YMTGXDN6.js → chunk-KC6TCAWV.js} +5 -5
  70. package/dist/{chunk-ROZJACKP.js → chunk-KKK7YTYN.js} +4 -1
  71. package/dist/chunk-KKK7YTYN.js.map +1 -0
  72. package/dist/{chunk-EC2AYKRX.js → chunk-L6W77GWW.js} +10 -24
  73. package/dist/chunk-L6W77GWW.js.map +1 -0
  74. package/dist/{chunk-ED35D32I.js → chunk-LQ4J7ELC.js} +2 -2
  75. package/dist/{chunk-YPR7DOPD.js → chunk-LTJAMRGI.js} +4 -4
  76. package/dist/{chunk-YPR7DOPD.js.map → chunk-LTJAMRGI.js.map} +1 -1
  77. package/dist/chunk-LUPVCGYK.js +63 -0
  78. package/dist/chunk-LUPVCGYK.js.map +1 -0
  79. package/dist/{chunk-RJ2THZ4H.js → chunk-MBUM2Y3L.js} +2 -2
  80. package/dist/{chunk-T5QAZIBO.js → chunk-MOXFPLD6.js} +3 -3
  81. package/dist/{chunk-O54DY26V.js → chunk-MXEWQKM7.js} +2 -2
  82. package/dist/{chunk-33L6XHU2.js → chunk-NUIJEGVD.js} +6 -6
  83. package/dist/{chunk-3E5WRQNQ.js → chunk-OXEAMU42.js} +529 -9
  84. package/dist/chunk-OXEAMU42.js.map +1 -0
  85. package/dist/{chunk-EOBJRBLC.js → chunk-QGJAGC2J.js} +2 -2
  86. package/dist/{chunk-SMIVW7XC.js → chunk-QIMFOCSH.js} +2 -2
  87. package/dist/{chunk-IJEZMWKA.js → chunk-SFOAQQDJ.js} +3 -3
  88. package/dist/{chunk-HRUULBBV.js → chunk-SHRRWOVY.js} +81 -4
  89. package/dist/chunk-SHRRWOVY.js.map +1 -0
  90. package/dist/{chunk-NINRTFSV.js → chunk-SINGJCUR.js} +5 -5
  91. package/dist/{chunk-ZPQVJEVQ.js → chunk-SK2CR6MW.js} +146 -2
  92. package/dist/chunk-SK2CR6MW.js.map +1 -0
  93. package/dist/{chunk-SEWF2O74.js → chunk-TGAHHCB6.js} +2 -2
  94. package/dist/{chunk-D75JXBV4.js → chunk-WN4GHSDH.js} +2 -2
  95. package/dist/{chunk-K4DWSPMW.js → chunk-WRGPE6AW.js} +2 -2
  96. package/dist/{chunk-GA5A6MJH.js → chunk-XGMCUY5P.js} +62 -116
  97. package/dist/chunk-XGMCUY5P.js.map +1 -0
  98. package/dist/{chunk-SDPDU2PM.js → chunk-YTMDF6S7.js} +2 -2
  99. package/dist/{chunk-ZDK2IW5F.js → chunk-Z7XEIAV4.js} +2 -2
  100. package/dist/{chunk-NHBEO3F3.js → chunk-ZCEI242W.js} +24 -24
  101. package/dist/{cli--yVN9yEV.d.ts → cli-BM4xQPp4.d.ts} +3 -3
  102. package/dist/cli.d.ts +7 -7
  103. package/dist/cli.js +35 -34
  104. package/dist/compounding/engine.d.ts +1 -1
  105. package/dist/compounding/engine.js +8 -7
  106. package/dist/compounding/preference-consolidator.d.ts +1 -1
  107. package/dist/compression-optimizer.d.ts +1 -1
  108. package/dist/config.d.ts +1 -1
  109. package/dist/config.js +4 -2
  110. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  111. package/dist/connectors/codex-materialize-runner.js +8 -7
  112. package/dist/connectors/codex-materialize.d.ts +1 -1
  113. package/dist/connectors/index.d.ts +1 -1
  114. package/dist/connectors/index.js +9 -8
  115. package/dist/consolidation-provenance-check.d.ts +1 -1
  116. package/dist/consolidation-undo.d.ts +1 -1
  117. package/dist/contradiction/index.d.ts +2 -2
  118. package/dist/conversation-index/backend.d.ts +1 -1
  119. package/dist/conversation-index/chunker.d.ts +1 -1
  120. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  121. package/dist/conversation-index/indexer.d.ts +1 -1
  122. package/dist/conversation-index/search.d.ts +1 -1
  123. package/dist/day-summary.d.ts +1 -1
  124. package/dist/delinearize.d.ts +1 -1
  125. package/dist/direct-answer-wiring.d.ts +1 -1
  126. package/dist/direct-answer.d.ts +1 -1
  127. package/dist/embedding-fallback.d.ts +1 -1
  128. package/dist/enrichment/index.d.ts +1 -1
  129. package/dist/entity-retrieval.d.ts +1 -1
  130. package/dist/entity-retrieval.js +8 -7
  131. package/dist/entity-schema.d.ts +1 -1
  132. package/dist/event-order-recall.js +2 -1
  133. package/dist/explicit-capture.d.ts +5 -5
  134. package/dist/explicit-capture.js +2 -2
  135. package/dist/explicit-cue-recall.js +2 -1
  136. package/dist/extraction-faithfulness.d.ts +1 -1
  137. package/dist/extraction-judge-telemetry.d.ts +1 -1
  138. package/dist/extraction-judge-training.d.ts +1 -1
  139. package/dist/extraction-judge.d.ts +1 -1
  140. package/dist/extraction.d.ts +14 -1
  141. package/dist/extraction.js +5 -3
  142. package/dist/fallback-llm.d.ts +1 -1
  143. package/dist/{forget-BEXG5PQC.js → forget-6SOIPUMQ.js} +3 -3
  144. package/dist/identity-continuity.d.ts +1 -1
  145. package/dist/importance.d.ts +1 -1
  146. package/dist/index.d.ts +123 -123
  147. package/dist/index.js +57 -56
  148. package/dist/index.js.map +1 -1
  149. package/dist/intent.d.ts +1 -1
  150. package/dist/lcm/engine.d.ts +1 -1
  151. package/dist/lcm/index.d.ts +1 -1
  152. package/dist/lcm/tools.d.ts +1 -1
  153. package/dist/lifecycle.d.ts +1 -1
  154. package/dist/live-connectors-runner.d.ts +1 -1
  155. package/dist/local-llm.d.ts +1 -1
  156. package/dist/maintenance/memory-governance.d.ts +1 -1
  157. package/dist/maintenance/memory-governance.js +8 -7
  158. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -7
  159. package/dist/maintenance/rebuild-memory-projection.js +9 -8
  160. package/dist/mcp-memory-inspector-app.d.ts +7 -7
  161. package/dist/memory-action-policy.d.ts +1 -1
  162. package/dist/memory-cache.d.ts +1 -1
  163. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  164. package/dist/memory-projection-store.d.ts +1 -1
  165. package/dist/memory-provenance.d.ts +1 -1
  166. package/dist/memory-worth-outcomes.d.ts +1 -1
  167. package/dist/models-json.d.ts +1 -1
  168. package/dist/namespaces/migrate.d.ts +2 -2
  169. package/dist/namespaces/migrate.js +9 -8
  170. package/dist/namespaces/principal.d.ts +1 -1
  171. package/dist/namespaces/search.d.ts +1 -1
  172. package/dist/namespaces/storage.d.ts +14 -3
  173. package/dist/namespaces/storage.js +8 -7
  174. package/dist/native-knowledge.d.ts +1 -1
  175. package/dist/operator-toolkit.d.ts +1 -1
  176. package/dist/operator-toolkit.js +14 -13
  177. package/dist/orchestration/maintenance.d.ts +2 -2
  178. package/dist/orchestration/maintenance.js +10 -9
  179. package/dist/{orchestrator-CJI4xdqV.d.ts → orchestrator-C9CDWAm6.d.ts} +4 -4
  180. package/dist/orchestrator.d.ts +5 -5
  181. package/dist/orchestrator.js +33 -31
  182. package/dist/patterns-cli.d.ts +1 -1
  183. package/dist/policy-runtime.d.ts +1 -1
  184. package/dist/provenance.d.ts +36 -2
  185. package/dist/provenance.js +5 -1
  186. package/dist/qmd-recall-cache.d.ts +1 -1
  187. package/dist/qmd.d.ts +1 -1
  188. package/dist/recall-disclosure-escalation.d.ts +1 -1
  189. package/dist/recall-explain-renderer.d.ts +1 -1
  190. package/dist/recall-explain-renderer.js +3 -3
  191. package/dist/recall-pipeline-stages.d.ts +15 -0
  192. package/dist/recall-pipeline-stages.js +3 -56
  193. package/dist/recall-pipeline-stages.js.map +1 -1
  194. package/dist/recall-planner-llm.d.ts +1 -1
  195. package/dist/recall-state.d.ts +1 -1
  196. package/dist/recall-tag-filter.d.ts +1 -1
  197. package/dist/recall-xray-cli.d.ts +1 -1
  198. package/dist/recall-xray-cli.js +4 -4
  199. package/dist/recall-xray-renderer.d.ts +1 -1
  200. package/dist/recall-xray-renderer.js +3 -3
  201. package/dist/recall-xray.d.ts +1 -1
  202. package/dist/recall-xray.js +2 -2
  203. package/dist/resolve-auth-token.d.ts +1 -1
  204. package/dist/response-guidance-recall.js +2 -1
  205. package/dist/resume-bundles.js +7 -5
  206. package/dist/retrieval-agents.d.ts +1 -1
  207. package/dist/retrieval-tiers.d.ts +1 -1
  208. package/dist/routing/engine.d.ts +1 -1
  209. package/dist/routing/store.d.ts +1 -1
  210. package/dist/schemas.d.ts +19 -0
  211. package/dist/schemas.js +1 -1
  212. package/dist/search/embed-helper.d.ts +1 -1
  213. package/dist/search/factory.d.ts +1 -1
  214. package/dist/search/index.d.ts +1 -1
  215. package/dist/search/lancedb-backend.d.ts +1 -1
  216. package/dist/search/meilisearch-backend.d.ts +1 -1
  217. package/dist/search/noop-backend.d.ts +1 -1
  218. package/dist/search/orama-backend.d.ts +1 -1
  219. package/dist/search/port.d.ts +1 -1
  220. package/dist/search/remote-backend.d.ts +1 -1
  221. package/dist/{semantic-DJR8_DMQ.d.ts → semantic-SLAa_prH.d.ts} +1 -1
  222. package/dist/{semantic-consolidation-BtUfv-AL.d.ts → semantic-consolidation-DgFXyALl.d.ts} +1 -1
  223. package/dist/semantic-consolidation.d.ts +2 -2
  224. package/dist/semantic-consolidation.js +9 -8
  225. package/dist/semantic-rule-promotion.js +8 -7
  226. package/dist/semantic-rule-verifier.d.ts +1 -1
  227. package/dist/semantic-rule-verifier.js +8 -7
  228. package/dist/session-observer-bands.d.ts +1 -1
  229. package/dist/session-observer-state.d.ts +1 -1
  230. package/dist/shared-context/manager.d.ts +1 -1
  231. package/dist/signal.d.ts +1 -1
  232. package/dist/storage.d.ts +13 -1
  233. package/dist/storage.js +7 -6
  234. package/dist/summarizer.d.ts +1 -1
  235. package/dist/summarizer.js +3 -2
  236. package/dist/summary-snapshot.d.ts +1 -1
  237. package/dist/summary-snapshot.js +2 -1
  238. package/dist/targeted-fact-recall.js +2 -1
  239. package/dist/temporal-supersession.d.ts +1 -1
  240. package/dist/temporal-validity.d.ts +1 -1
  241. package/dist/threading.d.ts +1 -1
  242. package/dist/tier-migration.d.ts +1 -1
  243. package/dist/tier-routing.d.ts +1 -1
  244. package/dist/topics.d.ts +1 -1
  245. package/dist/transcript.d.ts +1 -1
  246. package/dist/transcript.js +2 -2
  247. package/dist/{types-PuiPZ9iE.d.ts → types-MWKPZnM0.d.ts} +25 -1
  248. package/dist/types.d.ts +1 -1
  249. package/dist/types.js +1 -1
  250. package/dist/utility-runtime.d.ts +1 -1
  251. package/dist/utils/serialize-mutations.js +1 -1
  252. package/dist/verified-recall.js +8 -7
  253. package/package.json +2 -2
  254. package/src/access-http.ts +162 -0
  255. package/src/access-service.ts +215 -0
  256. package/src/admin/admin-surfaces.test.ts +458 -0
  257. package/src/admin/admin-surfaces.ts +819 -0
  258. package/src/event-order-recall.test.ts +53 -0
  259. package/src/event-order-recall.ts +61 -37
  260. package/src/explicit-cue-recall.ts +21 -1
  261. package/src/extraction.ts +91 -6
  262. package/src/namespaces/catalog.test.ts +222 -14
  263. package/src/namespaces/catalog.ts +54 -187
  264. package/src/namespaces/storage.ts +87 -80
  265. package/src/orchestrator.ts +46 -5
  266. package/src/provenance-extraction.test.ts +838 -0
  267. package/src/provenance.ts +413 -0
  268. package/src/recall-pipeline-parity.test.ts +288 -0
  269. package/src/recall-pipeline-stages.test.ts +43 -0
  270. package/src/recall-pipeline-stages.ts +22 -0
  271. package/src/response-guidance-recall.ts +32 -36
  272. package/src/schemas.ts +7 -0
  273. package/src/storage.ts +23 -0
  274. package/src/summary-snapshot.test.ts +63 -1
  275. package/src/summary-snapshot.ts +61 -80
  276. package/src/targeted-fact-recall.ts +25 -32
  277. package/src/types.ts +24 -0
  278. package/src/utils/serialize-mutations.ts +10 -6
  279. package/dist/chunk-3E5WRQNQ.js.map +0 -1
  280. package/dist/chunk-DR2JTSLZ.js.map +0 -1
  281. package/dist/chunk-EC2AYKRX.js.map +0 -1
  282. package/dist/chunk-FN2SM5SN.js.map +0 -1
  283. package/dist/chunk-GA5A6MJH.js.map +0 -1
  284. package/dist/chunk-HRUULBBV.js.map +0 -1
  285. package/dist/chunk-PQG4T5V3.js.map +0 -1
  286. package/dist/chunk-R5DB26G6.js.map +0 -1
  287. package/dist/chunk-ROZJACKP.js.map +0 -1
  288. package/dist/chunk-UU6MVCJ6.js.map +0 -1
  289. package/dist/chunk-X74FJSW7.js.map +0 -1
  290. package/dist/chunk-XJNBEDFE.js.map +0 -1
  291. package/dist/chunk-YXLT4EMM.js.map +0 -1
  292. package/dist/chunk-ZPQVJEVQ.js.map +0 -1
  293. /package/dist/{chunk-PCZR32VL.js.map → chunk-3JJWNZTT.js.map} +0 -0
  294. /package/dist/{chunk-YXIFA36P.js.map → chunk-6TAETM63.js.map} +0 -0
  295. /package/dist/{chunk-6JDGADXK.js.map → chunk-6VVP6NK7.js.map} +0 -0
  296. /package/dist/{chunk-CHM274U6.js.map → chunk-AMNLZ6SF.js.map} +0 -0
  297. /package/dist/{chunk-JX3YZVII.js.map → chunk-CZJ6QSKG.js.map} +0 -0
  298. /package/dist/{chunk-GYVVQYA3.js.map → chunk-EOOVJK2U.js.map} +0 -0
  299. /package/dist/{chunk-JKW5XSWC.js.map → chunk-EYJD6KIO.js.map} +0 -0
  300. /package/dist/{chunk-XY4WJTEX.js.map → chunk-EZR35XHX.js.map} +0 -0
  301. /package/dist/{chunk-2NWHLAXX.js.map → chunk-FVI5B7DE.js.map} +0 -0
  302. /package/dist/{chunk-PONNZ54D.js.map → chunk-GY3SKOS4.js.map} +0 -0
  303. /package/dist/{chunk-U33LWTQQ.js.map → chunk-HV57RHMD.js.map} +0 -0
  304. /package/dist/{chunk-RC3CNIPK.js.map → chunk-IO5NQEGZ.js.map} +0 -0
  305. /package/dist/{chunk-HDLC75NX.js.map → chunk-IX72AAMZ.js.map} +0 -0
  306. /package/dist/{chunk-G5PKTQ5J.js.map → chunk-JTKFZMZ7.js.map} +0 -0
  307. /package/dist/{chunk-YMTGXDN6.js.map → chunk-KC6TCAWV.js.map} +0 -0
  308. /package/dist/{chunk-ED35D32I.js.map → chunk-LQ4J7ELC.js.map} +0 -0
  309. /package/dist/{chunk-RJ2THZ4H.js.map → chunk-MBUM2Y3L.js.map} +0 -0
  310. /package/dist/{chunk-T5QAZIBO.js.map → chunk-MOXFPLD6.js.map} +0 -0
  311. /package/dist/{chunk-O54DY26V.js.map → chunk-MXEWQKM7.js.map} +0 -0
  312. /package/dist/{chunk-33L6XHU2.js.map → chunk-NUIJEGVD.js.map} +0 -0
  313. /package/dist/{chunk-EOBJRBLC.js.map → chunk-QGJAGC2J.js.map} +0 -0
  314. /package/dist/{chunk-SMIVW7XC.js.map → chunk-QIMFOCSH.js.map} +0 -0
  315. /package/dist/{chunk-IJEZMWKA.js.map → chunk-SFOAQQDJ.js.map} +0 -0
  316. /package/dist/{chunk-NINRTFSV.js.map → chunk-SINGJCUR.js.map} +0 -0
  317. /package/dist/{chunk-SEWF2O74.js.map → chunk-TGAHHCB6.js.map} +0 -0
  318. /package/dist/{chunk-D75JXBV4.js.map → chunk-WN4GHSDH.js.map} +0 -0
  319. /package/dist/{chunk-K4DWSPMW.js.map → chunk-WRGPE6AW.js.map} +0 -0
  320. /package/dist/{chunk-SDPDU2PM.js.map → chunk-YTMDF6S7.js.map} +0 -0
  321. /package/dist/{chunk-ZDK2IW5F.js.map → chunk-Z7XEIAV4.js.map} +0 -0
  322. /package/dist/{chunk-NHBEO3F3.js.map → chunk-ZCEI242W.js.map} +0 -0
  323. /package/dist/{forget-BEXG5PQC.js.map → forget-6SOIPUMQ.js.map} +0 -0
@@ -1,18 +1,14 @@
1
- import {
2
- mkdir,
3
- open,
4
- readFile,
5
- stat,
6
- unlink,
7
- utimes,
8
- writeFile,
9
- } from "node:fs/promises";
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
10
2
  import path from "node:path";
11
3
  import { z } from "zod";
12
4
  import {
13
5
  encodeStoragePathSegment,
14
6
  resolvePathInsideStorageRoot,
15
7
  } from "./storage-paths.js";
8
+ import {
9
+ serializeMutations,
10
+ withHeldFileLock,
11
+ } from "./utils/serialize-mutations.js";
16
12
  import type { HourlySummary } from "./types.js";
17
13
 
18
14
  const summarySnapshotSchemaVersion = 1;
@@ -34,7 +30,9 @@ const SummarySnapshotSchema = z.object({
34
30
 
35
31
  type SummarySnapshot = z.infer<typeof SummarySnapshotSchema>;
36
32
 
37
- const summarySnapshotUpserts = new Map<string, Promise<void>>();
33
+ // Lock timings for the cross-process summary-snapshot file lock. These are
34
+ // passed straight through to the shared `withHeldFileLock` utility (issue
35
+ // #1524 adoption); the previous bespoke lock used the same numbers.
38
36
  const summarySnapshotLockTimeoutMs = 5_000;
39
37
  const summarySnapshotLockStaleMs = 30_000;
40
38
  const summarySnapshotLockHeartbeatMs = Math.max(
@@ -137,31 +135,65 @@ export async function writeSummarySnapshot(
137
135
  await writeFile(filePath, JSON.stringify(payload, null, 2), "utf-8");
138
136
  }
139
137
 
138
+ // ── Concurrency primitives (issue #1524 adoption) ─────────────────────────
139
+ //
140
+ // Summary-snapshot upserts were previously guarded by TWO bespoke serializers:
141
+ // 1. an in-process `summarySnapshotUpserts` map keyed by sessionKey that
142
+ // chained each upsert off the prior one's release (mirroring
143
+ // `serializeMutations`), and
144
+ // 2. an on-disk `withExclusiveSummarySnapshotFileLock` that re-implemented
145
+ // `open(path, "wx")` acquire, mtime heartbeat, stale-break, and
146
+ // ownership-checked release.
147
+ // Both now delegate to the shared utility so there is ONE home for each
148
+ // primitive (`serializeMutations` for in-process, `withHeldFileLock` for
149
+ // cross-process). The behavior contract is preserved:
150
+ // - in-process upserts for the SAME sessionKey are strictly serialized
151
+ // (read-merge-write cannot interleave);
152
+ // - a cross-process holder blocks up to `summarySnapshotLockTimeoutMs`, then
153
+ // the upsert FAILS (a snapshot is advisory; we never race a read-merge-write
154
+ // unlocked). To preserve this strictness on top of a best-effort utility,
155
+ // the work callback throws when `acquired === false`.
156
+
140
157
  async function withSummarySnapshotLock<T>(
141
158
  memoryDir: string,
142
159
  sessionKey: string,
143
160
  work: () => Promise<T>,
144
161
  ): Promise<T> {
145
- const previous = summarySnapshotUpserts.get(sessionKey) ?? Promise.resolve();
146
- let release!: () => void;
147
- const current = new Promise<void>((resolve) => {
148
- release = resolve;
149
- });
150
- const chained = previous.then(() => current);
151
- summarySnapshotUpserts.set(sessionKey, chained);
152
-
153
- await previous;
154
- try {
155
- return await withExclusiveSummarySnapshotFileLock(
162
+ // In-process serialization (one upsert per sessionKey at a time). The
163
+ // serializer recovers from rejection, so a failed upsert never poisons the
164
+ // next one matching the previous chain's `.then(noop, noop)` recovery.
165
+ return serializeMutations(`summary-snapshot:${sessionKey}`, () =>
166
+ // Cross-process mutex via the shared utility. The lock path, stale
167
+ // threshold, bounded wait, and heartbeat cadence all flow through; the
168
+ // utility's replacement-safe stale break (NG7Bg) and ownership-checked
169
+ // release are stronger than the bare `unlink` this module used before.
170
+ withHeldFileLock(
156
171
  summarySnapshotLockPath(memoryDir, sessionKey),
157
- work,
158
- );
159
- } finally {
160
- release();
161
- if (summarySnapshotUpserts.get(sessionKey) === chained) {
162
- summarySnapshotUpserts.delete(sessionKey);
163
- }
164
- }
172
+ {
173
+ staleMs: summarySnapshotLockStaleMs,
174
+ maxWaitMs: summarySnapshotLockTimeoutMs,
175
+ heartbeatMs: summarySnapshotLockHeartbeatMs,
176
+ },
177
+ async (acquired) => {
178
+ // Strict-fail when the lock could not be acquired: the upsert is a
179
+ // read-merge-write, so a best-effort unlocked run would clobber a
180
+ // concurrent writer. The utility's `acquired === false` covers BOTH a
181
+ // genuine contention timeout AND a filesystem acquire failure (lock-dir
182
+ // mkdir/open/permission errors — the advisory lock is best-effort, so
183
+ // the util degrades rather than throwing). The bespoke lock this
184
+ // replaced propagated fs errors verbatim and reserved the timeout
185
+ // message for contention; we no longer claim "timed out" for an fs
186
+ // failure (cursor Low 25143f4f) — the message names both causes so
187
+ // upstream fail-open (runHourly) is unchanged but debugging is honest.
188
+ if (!acquired) {
189
+ throw new Error(
190
+ "could not acquire summary snapshot lock (contention timeout or filesystem error)",
191
+ );
192
+ }
193
+ return work();
194
+ },
195
+ ),
196
+ );
165
197
  }
166
198
 
167
199
  export async function upsertSummarySnapshot(
@@ -185,54 +217,3 @@ export async function upsertSummarySnapshot(
185
217
  await writeSummarySnapshot(memoryDir, summary.sessionKey, next);
186
218
  });
187
219
  }
188
-
189
- async function withExclusiveSummarySnapshotFileLock<T>(
190
- lockPath: string,
191
- callback: () => Promise<T>,
192
- ): Promise<T> {
193
- await mkdir(path.dirname(lockPath), { recursive: true });
194
- const startedAt = Date.now();
195
-
196
- while (true) {
197
- try {
198
- const handle = await open(lockPath, "wx");
199
- let heartbeat: NodeJS.Timeout | null = null;
200
- if (summarySnapshotLockHeartbeatMs > 0) {
201
- heartbeat = setInterval(() => {
202
- void utimes(lockPath, new Date(), new Date()).catch(() => undefined);
203
- }, summarySnapshotLockHeartbeatMs);
204
- heartbeat.unref?.();
205
- }
206
- try {
207
- return await callback();
208
- } finally {
209
- if (heartbeat) clearInterval(heartbeat);
210
- await handle.close().catch(() => undefined);
211
- await unlink(lockPath).catch(() => undefined);
212
- }
213
- } catch (error) {
214
- if (!isAlreadyExistsError(error)) throw error;
215
- try {
216
- const lockStat = await stat(lockPath);
217
- if (Date.now() - lockStat.mtimeMs > summarySnapshotLockStaleMs) {
218
- await unlink(lockPath).catch(() => undefined);
219
- continue;
220
- }
221
- } catch {
222
- continue;
223
- }
224
- if (Date.now() - startedAt > summarySnapshotLockTimeoutMs) {
225
- throw new Error("timed out acquiring summary snapshot lock");
226
- }
227
- await sleep(10);
228
- }
229
- }
230
- }
231
-
232
- function isAlreadyExistsError(error: unknown): boolean {
233
- return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
234
- }
235
-
236
- function sleep(ms: number): Promise<void> {
237
- return new Promise((resolve) => setTimeout(resolve, ms));
238
- }
@@ -9,6 +9,11 @@ import {
9
9
  resolveLcmReadSessionIds,
10
10
  } from "./lcm-fallback-read.js";
11
11
 
12
+ import {
13
+ unifiedDedupeAndRank,
14
+ type RankedEvidenceItem,
15
+ } from "./recall-pipeline-stages.js";
16
+
12
17
  export interface TargetedFactRecallOptions {
13
18
  engine: ExplicitCueRecallEngine | null | undefined;
14
19
  sessionId?: string;
@@ -27,10 +32,6 @@ export interface TargetedFactRecallOptions {
27
32
  title?: string;
28
33
  }
29
34
 
30
- interface RankedEvidenceItem extends EvidencePackItem {
31
- rank: number;
32
- }
33
-
34
35
  const DEFAULT_MAX_SEARCH_RESULTS = 48;
35
36
  const DEFAULT_SCAN_WINDOW_TURNS = 8;
36
37
  const DEFAULT_SCAN_WINDOW_TOKENS = 12_000;
@@ -210,38 +211,30 @@ async function collectTargetedFactScanItems(
210
211
  return items;
211
212
  }
212
213
 
214
+ /**
215
+ * Issue #1539 PR3: targeted-fact now routes dedup/score/threshold/sort through
216
+ * the unified spine (`unifiedDedupeAndRank`). The divergence that lived inline
217
+ * here — append-normalized-numeric-cues content transform, relevance scoring on
218
+ * ORIGINAL content, default DESC turn-index ordering with -1 sentinel for
219
+ * missing turns — is now declared config on the spine. The score and
220
+ * appendNormalizedNumericCues helpers stay in this module because they are
221
+ * genuinely per-tier policy; only the duplicated dedup/sort/threshold machinery
222
+ * moved out.
223
+ *
224
+ * Behavior is byte-for-byte identical to the inline implementation it replaces
225
+ * (the spine was extracted to match it exactly; see recall-pipeline-stages.ts).
226
+ * The targeted-fact-recall.test.ts suite (42 cases, incl. the search/scan
227
+ * ordering and summary insertion tests) is the characterization.
228
+ */
213
229
  function rankAndDedupeTargetedFactItems(
214
230
  items: EvidencePackItem[],
215
231
  query: string,
216
232
  ): RankedEvidenceItem[] {
217
- const seenIds = new Set<string>();
218
- const seenContent = new Set<string>();
219
- const ranked: RankedEvidenceItem[] = [];
220
-
221
- for (const item of items) {
222
- const id = item.id ?? (
223
- item.sessionId && typeof item.turnIndex === "number"
224
- ? `${item.sessionId}:${item.turnIndex}`
225
- : undefined
226
- );
227
- if (id && seenIds.has(id)) continue;
228
- const contentKey = item.content.toLowerCase().replace(/\s+/g, " ").trim();
229
- if (seenContent.has(contentKey)) continue;
230
- if (id) seenIds.add(id);
231
- seenContent.add(contentKey);
232
- ranked.push({
233
- ...item,
234
- content: appendNormalizedNumericCues(item.content),
235
- rank: scoreTargetedFactEvidence(item, query),
236
- });
237
- }
238
-
239
- return ranked.sort((left, right) => {
240
- if (right.rank !== left.rank) return right.rank - left.rank;
241
- const leftTurn = typeof left.turnIndex === "number" ? left.turnIndex : -1;
242
- const rightTurn = typeof right.turnIndex === "number" ? right.turnIndex : -1;
243
- if (rightTurn !== leftTurn) return rightTurn - leftTurn;
244
- return (right.score ?? 0) - (left.score ?? 0);
233
+ return unifiedDedupeAndRank(items, {
234
+ query,
235
+ intents: [],
236
+ scoreEvidence: (item, q) => scoreTargetedFactEvidence(item, q),
237
+ transformContent: (content) => appendNormalizedNumericCues(content),
245
238
  });
246
239
  }
247
240
 
package/src/types.ts CHANGED
@@ -2852,6 +2852,30 @@ export interface ExtractedFact {
2852
2852
  * "no verified span" and skip gracefully.
2853
2853
  */
2854
2854
  sources?: ProvenanceSource[];
2855
+ /**
2856
+ * Coarse provenance strength tag (issue #1575 PR 2). Set by the extraction
2857
+ * validator: "verified" when the quote was located in source turns,
2858
+ * "unverified" when the quote survived but no offsets were recoverable.
2859
+ * Absent when `provenance.enabled` is false or no quote was provided —
2860
+ * readers treat absent as "none" (rule 34 spirit).
2861
+ */
2862
+ provenance?: "verified" | "unverified" | "none";
2863
+ /**
2864
+ * Transient LLM-provided supporting quote (issue #1575 PR 2). Consumed by
2865
+ * the post-parse validator to build `sources`, then stripped before the
2866
+ * fact reaches persistence. NEVER included in content-hash dedup (rule 23 /
2867
+ * checklist §13). Absent on facts that have already passed the validator.
2868
+ */
2869
+ quote?: string;
2870
+ /**
2871
+ * Transient requireSpans signal (issue #1575 PR 2). Set by the provenance
2872
+ * validator (`ProvenanceBuildResult.requireSpansPending`) when
2873
+ * `provenance.requireSpans` is enabled and the quote could not be located
2874
+ * in any source turn. Read by the persist path to route the fact to
2875
+ * `pending_review` instead of `active`. Stripped before persistence —
2876
+ * it never reaches frontmatter (chatgpt-codex-connector thread 4xB).
2877
+ */
2878
+ requireSpansPending?: boolean;
2855
2879
  promptedByQuestion?: string;
2856
2880
  /**
2857
2881
  * Whether this fact is project-scoped or globally applicable.
@@ -670,10 +670,14 @@ async function lockHeldBySelf(held: HeldLock): Promise<boolean> {
670
670
  }
671
671
 
672
672
  function sleep(ms: number): Promise<void> {
673
- const { promise, resolve } = Promise.withResolvers<void>();
674
- // NOT unref'd: this polls inside an awaited acquire loop, so the caller's
675
- // await chain keeps the loop alive; unref would let Node exit mid-poll when
676
- // nothing else is pending (the heartbeat interval IS unref'd separately).
677
- setTimeout(resolve, ms);
678
- return promise;
673
+ // Manual deferred instead of Promise.withResolvers (ES2024) — plugin-openclaw's
674
+ // standalone tsconfig targets ES2022 lib and this module is reachable from its
675
+ // type graph, so withResolvers would TS2550 there (same fix as
676
+ // extraction-faithfulness.ts:467).
677
+ return new Promise<void>((resolve) => {
678
+ // NOT unref'd: this polls inside an awaited acquire loop, so the caller's
679
+ // await chain keeps the loop alive; unref would let Node exit mid-poll when
680
+ // nothing else is pending (the heartbeat interval IS unref'd separately).
681
+ setTimeout(resolve, ms);
682
+ });
679
683
  }