@remnic/core 10.0.6 → 10.0.8

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 (400) hide show
  1. package/dist/access-admin-ops-surface.js +66 -64
  2. package/dist/access-authorization-probe.js +67 -65
  3. package/dist/access-boundary.js +66 -64
  4. package/dist/access-cli.js +133 -131
  5. package/dist/access-cli.js.map +1 -1
  6. package/dist/access-extraction-force-flush.js +66 -64
  7. package/dist/access-http-briefing.js +67 -65
  8. package/dist/access-http-query.js +68 -66
  9. package/dist/access-http.js +90 -88
  10. package/dist/access-idempotency.d.ts.map +1 -1
  11. package/dist/access-idempotency.js +2 -1
  12. package/dist/access-identity-continuity-surface.js +66 -64
  13. package/dist/access-lcm-surface.js +66 -64
  14. package/dist/access-mcp.js +79 -77
  15. package/dist/access-namespace-preflight.js +66 -64
  16. package/dist/access-observe-write-category.js +15 -14
  17. package/dist/access-observe-write-surface.js +66 -64
  18. package/dist/access-offline-manifest.js +12 -11
  19. package/dist/access-operations-batch.js +70 -68
  20. package/dist/access-operations.js +77 -75
  21. package/dist/access-recall-concurrency.js +66 -64
  22. package/dist/access-recall-response.js +66 -64
  23. package/dist/access-recall-surface.js +66 -64
  24. package/dist/access-schema.js +10 -9
  25. package/dist/access-service.js +66 -64
  26. package/dist/access-surface-catalog.js +68 -66
  27. package/dist/access-surface-catalog.js.map +1 -1
  28. package/dist/active-recall.js +28 -27
  29. package/dist/active-recall.js.map +1 -1
  30. package/dist/adapters/index.js +4 -4
  31. package/dist/adapters/registry.js +2 -2
  32. package/dist/{auto-sync-FN7E3OTO.js → auto-sync-WSJAOLOP.js} +8 -7
  33. package/dist/{auto-sync-FN7E3OTO.js.map → auto-sync-WSJAOLOP.js.map} +1 -1
  34. package/dist/briefing.js +20 -19
  35. package/dist/buffer.js +13 -12
  36. package/dist/{capsule-merge-42GJGDUC.js → capsule-merge-M4HETD27.js} +5 -4
  37. package/dist/{capsule-merge-42GJGDUC.js.map → capsule-merge-M4HETD27.js.map} +1 -1
  38. package/dist/causal-behavior.js +2 -2
  39. package/dist/causal-chain.js +2 -2
  40. package/dist/causal-consolidation.js +23 -22
  41. package/dist/causal-consolidation.js.map +1 -1
  42. package/dist/causal-retrieval.js +2 -2
  43. package/dist/causal-trajectory-graph.js +4 -3
  44. package/dist/causal-trajectory-graph.js.map +1 -1
  45. package/dist/causal-trajectory.js +1 -1
  46. package/dist/{chunk-OZABSIOV.js → chunk-2AFHZTPI.js} +2 -2
  47. package/dist/{chunk-UK5EH7AI.js → chunk-2CXQZXWM.js} +3 -3
  48. package/dist/{chunk-D6M3VKMY.js → chunk-2K7D6EFT.js} +3 -3
  49. package/dist/{chunk-RIEGCK2W.js → chunk-2KRNPFPK.js} +2 -2
  50. package/dist/{chunk-N7QV3CMX.js → chunk-2NCBDGND.js} +2 -2
  51. package/dist/{chunk-XQSJXNWC.js → chunk-3ENX2RB4.js} +2 -2
  52. package/dist/{chunk-CLCMDKTB.js → chunk-3I3U6FFT.js} +2 -2
  53. package/dist/{chunk-WWLAKRMX.js → chunk-3NFN4Y4P.js} +5 -5
  54. package/dist/{chunk-I56MTWE7.js → chunk-3R6SLDTH.js} +2 -2
  55. package/dist/{chunk-QEPL7KIZ.js → chunk-3VTNNO2B.js} +6 -6
  56. package/dist/{chunk-QWUJWBZ5.js → chunk-4G4B3Z2B.js} +2 -2
  57. package/dist/{chunk-R7QY5ZVB.js → chunk-4NDWE44P.js} +2 -2
  58. package/dist/{chunk-KCCZFDJD.js → chunk-4OKPH6FG.js} +2 -2
  59. package/dist/{chunk-I25RQA65.js → chunk-55ZVZBX4.js} +2 -2
  60. package/dist/{chunk-ENNC3RZ6.js → chunk-5EOV7ANU.js} +2 -2
  61. package/dist/{chunk-ANZXWOYD.js → chunk-5FNVK7MW.js} +2 -2
  62. package/dist/{chunk-VFUEZZBS.js → chunk-5JMI26Q7.js} +5 -4
  63. package/dist/chunk-5JMI26Q7.js.map +1 -0
  64. package/dist/{chunk-KSUOM3YU.js → chunk-5NOPZYNI.js} +11 -11
  65. package/dist/{chunk-7LYRFI5A.js → chunk-5Q4NQNW7.js} +2 -2
  66. package/dist/chunk-5VC7J76U.js +134 -0
  67. package/dist/chunk-5VC7J76U.js.map +1 -0
  68. package/dist/{chunk-L3PWXD73.js → chunk-6PHB45IU.js} +2 -2
  69. package/dist/{chunk-CHDGJJV6.js → chunk-6VAHJ2F6.js} +2 -2
  70. package/dist/{chunk-KQT4DRKF.js → chunk-76KHEHT2.js} +2 -2
  71. package/dist/chunk-7LEQREP2.js +9 -0
  72. package/dist/chunk-7LEQREP2.js.map +1 -0
  73. package/dist/{chunk-SWRN6U7Q.js → chunk-7O252IE6.js} +2 -2
  74. package/dist/{chunk-U6HWKOGD.js → chunk-7OAIOE5P.js} +2 -2
  75. package/dist/{chunk-RSMIRLKM.js → chunk-7UX44C4N.js} +2 -2
  76. package/dist/{chunk-DJMVSUPK.js → chunk-A6G7K273.js} +4 -4
  77. package/dist/{chunk-VC4J4UTI.js → chunk-AAM66QCP.js} +5 -5
  78. package/dist/{chunk-TZQOCQXB.js → chunk-AL6EHLB5.js} +2 -2
  79. package/dist/{chunk-IJ4FEGZR.js → chunk-AMFCRZYB.js} +2 -2
  80. package/dist/{chunk-4K2H4KTR.js → chunk-AV46CT77.js} +3 -3
  81. package/dist/{chunk-7PZHH4KC.js → chunk-AZEZSQ5R.js} +23 -2
  82. package/dist/chunk-AZEZSQ5R.js.map +1 -0
  83. package/dist/{chunk-VZBW6CDG.js → chunk-BOOFTFFE.js} +1 -1
  84. package/dist/{chunk-2UF42WXV.js → chunk-BPY4RRTF.js} +16 -16
  85. package/dist/{chunk-2U3R3DDH.js → chunk-BTJ6CAIA.js} +2 -2
  86. package/dist/{chunk-GF4H3B3R.js → chunk-C3WJNRGR.js} +3 -3
  87. package/dist/{chunk-SIYZDT2V.js → chunk-CBP4HWCL.js} +3 -3
  88. package/dist/{chunk-GEGUBU3D.js → chunk-CSUAHUOH.js} +3 -3
  89. package/dist/{chunk-AJ6ORARY.js → chunk-DGRMWDQY.js} +12 -12
  90. package/dist/chunk-DGRMWDQY.js.map +1 -0
  91. package/dist/{chunk-BNMI3JBV.js → chunk-DXHVD4DS.js} +3 -3
  92. package/dist/{chunk-GE6HETIF.js → chunk-E5274WUC.js} +2 -2
  93. package/dist/{chunk-2COXDQ6C.js → chunk-E6KXJSMA.js} +2 -2
  94. package/dist/{chunk-FFAZ2XFU.js → chunk-EHRE7ZG3.js} +5 -6
  95. package/dist/chunk-EHRE7ZG3.js.map +1 -0
  96. package/dist/{chunk-CCMXCZLT.js → chunk-FBVLTTVV.js} +7 -7
  97. package/dist/{chunk-XVC7JU2N.js → chunk-FQD2KPQH.js} +2 -2
  98. package/dist/{chunk-SNXBXYUE.js → chunk-GDI64ITR.js} +3 -3
  99. package/dist/{chunk-MH2DXDN6.js → chunk-GSAZBZMA.js} +2 -2
  100. package/dist/{chunk-MULNBSPP.js → chunk-HT2C4EXO.js} +2 -2
  101. package/dist/{chunk-EMVJU7WC.js → chunk-HZVYDWUP.js} +2 -2
  102. package/dist/{chunk-XPRAOTJY.js → chunk-IJWEXCWF.js} +2 -2
  103. package/dist/{chunk-L2VS27PZ.js → chunk-IOM5QSNR.js} +4 -4
  104. package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
  105. package/dist/{chunk-TDMNADPI.js → chunk-JK3DYMOC.js} +2 -2
  106. package/dist/{chunk-SZXPKUMN.js → chunk-JSIQSZXI.js} +4 -4
  107. package/dist/{chunk-KQI2PKYP.js → chunk-JTUKDLAD.js} +2 -2
  108. package/dist/{chunk-TL4PM7PC.js → chunk-K3DZ3G5I.js} +2 -2
  109. package/dist/{chunk-WG4TMZJ2.js → chunk-KDYQYMJZ.js} +2 -2
  110. package/dist/{chunk-N4PYB235.js → chunk-KI6UOSNR.js} +2 -2
  111. package/dist/{chunk-FC6RCOIU.js → chunk-KRIEQCKE.js} +2 -2
  112. package/dist/{chunk-EQUD7FP4.js → chunk-KYY4EACB.js} +2 -2
  113. package/dist/{chunk-QMFKW4OU.js → chunk-L3Z4NXDO.js} +3 -3
  114. package/dist/{chunk-KE5PWLI6.js → chunk-LOFVW6JA.js} +3 -3
  115. package/dist/{chunk-46WM6JX2.js → chunk-LZKOVXMX.js} +2 -2
  116. package/dist/{chunk-JMF5Q4JY.js → chunk-MAJ2OKE4.js} +9 -9
  117. package/dist/{chunk-U6OXJQEH.js → chunk-MB5EJ2CT.js} +5 -5
  118. package/dist/{chunk-VUEG3TZ4.js → chunk-MVRIW6MI.js} +2 -2
  119. package/dist/{chunk-TGF43K66.js → chunk-MZBWIJJN.js} +9 -9
  120. package/dist/{chunk-QGLEM46C.js → chunk-N44GZ73R.js} +8 -8
  121. package/dist/{chunk-63UNVGZW.js → chunk-N6UMXWBA.js} +4 -4
  122. package/dist/{chunk-FLV7M7CT.js → chunk-NAHUBSUF.js} +2 -2
  123. package/dist/{chunk-S5TGRZWY.js → chunk-NXLQQ6WI.js} +3 -3
  124. package/dist/{chunk-DTXN4NVD.js → chunk-NYVKLB2I.js} +46 -46
  125. package/dist/chunk-NYVKLB2I.js.map +1 -0
  126. package/dist/{chunk-YJAOYEWI.js → chunk-OC6JYPZX.js} +21 -44
  127. package/dist/chunk-OC6JYPZX.js.map +1 -0
  128. package/dist/{chunk-5AYUHSAU.js → chunk-OFCHT2TN.js} +2 -2
  129. package/dist/{chunk-HRZZJ4XB.js → chunk-P2S6P7X6.js} +2 -2
  130. package/dist/{chunk-OGVJXIHX.js → chunk-PBVNVKYN.js} +2 -2
  131. package/dist/{chunk-2CP577K6.js → chunk-PPIASWWR.js} +2 -2
  132. package/dist/{chunk-6C76FZRM.js → chunk-QFIPSKPC.js} +2 -2
  133. package/dist/{chunk-Q562GF7J.js → chunk-QN77HA6P.js} +2 -2
  134. package/dist/{chunk-MFZACYZ6.js → chunk-QUNDYIYZ.js} +3 -3
  135. package/dist/{chunk-L34W4W4I.js → chunk-QW7G7PWN.js} +2 -2
  136. package/dist/{chunk-W5XWHTDO.js → chunk-QZZPUREO.js} +3 -3
  137. package/dist/{chunk-JA72X46J.js → chunk-R2AWYR4Q.js} +2 -2
  138. package/dist/{chunk-YRULQW5J.js → chunk-RBJQYMMT.js} +4 -4
  139. package/dist/{chunk-6KHF6PAB.js → chunk-RH6QEGCT.js} +3 -3
  140. package/dist/{chunk-QRZMJ2WN.js → chunk-RNPJ4GQA.js} +2 -2
  141. package/dist/{chunk-TRBLJU6Y.js → chunk-S4GUMZRB.js} +40 -40
  142. package/dist/{chunk-MQNOIH2C.js → chunk-SQ2O52SU.js} +3 -3
  143. package/dist/{chunk-EP5WXE2G.js → chunk-TCYLCPC6.js} +2 -2
  144. package/dist/{chunk-7CZIKCJR.js → chunk-V4WSQYO6.js} +82 -82
  145. package/dist/{chunk-7CZIKCJR.js.map → chunk-V4WSQYO6.js.map} +1 -1
  146. package/dist/{chunk-PO7NXNGC.js → chunk-VFTK5WKI.js} +2 -2
  147. package/dist/{chunk-JA54KIYD.js → chunk-VSHRMIJH.js} +2 -2
  148. package/dist/{chunk-5BPXMAUP.js → chunk-VUQDJ3JB.js} +4 -4
  149. package/dist/{chunk-7CXL25AA.js → chunk-W4RLOZOG.js} +3 -3
  150. package/dist/{chunk-LHRQBMJN.js → chunk-WADSXS4K.js} +2 -2
  151. package/dist/{chunk-Y7427SL7.js → chunk-WCGJK4NQ.js} +4 -4
  152. package/dist/{chunk-37HCPM56.js → chunk-WJLGUY27.js} +18 -18
  153. package/dist/{chunk-YGPXV546.js → chunk-WPFSZZ35.js} +2 -2
  154. package/dist/{chunk-IM2GO42H.js → chunk-WVHRNAXL.js} +4 -4
  155. package/dist/chunk-WVHRNAXL.js.map +1 -0
  156. package/dist/{chunk-UXIZ5XN5.js → chunk-XLIK2VDE.js} +3 -3
  157. package/dist/{chunk-64S6X4IU.js → chunk-XTN54NML.js} +4 -4
  158. package/dist/{chunk-2UPTRDGM.js → chunk-Y6DZ33PA.js} +4 -4
  159. package/dist/{chunk-4JNTGPBR.js → chunk-YAF3NRNC.js} +2 -2
  160. package/dist/{chunk-IFCKHPY4.js → chunk-YDH2FSDI.js} +2 -2
  161. package/dist/{chunk-L6GNS5GB.js → chunk-YS7SA4HD.js} +2 -2
  162. package/dist/{chunk-EIFYYHAF.js → chunk-YYO447A7.js} +4 -4
  163. package/dist/{chunk-75PT4N7Q.js → chunk-ZI7LMSNI.js} +2 -2
  164. package/dist/{chunk-EUT2WCWS.js → chunk-ZQ3WU6JO.js} +2 -2
  165. package/dist/{chunk-YJEUHGZZ.js → chunk-ZQYAE2C5.js} +2 -2
  166. package/dist/{chunk-JYG2334B.js → chunk-ZSJGYC3C.js} +2 -2
  167. package/dist/cli.js +108 -106
  168. package/dist/coding/export-okf-codegraph.js +20 -19
  169. package/dist/coding/export-okf-codegraph.js.map +1 -1
  170. package/dist/coding/pre-action-gate.js +2 -2
  171. package/dist/compounding/engine.js +21 -20
  172. package/dist/config.js +28 -27
  173. package/dist/connectors/codex-materialize-runner.js +20 -19
  174. package/dist/connectors/index.js +20 -19
  175. package/dist/consolidation-provenance-check.js +5 -4
  176. package/dist/consolidation-undo.js +4 -3
  177. package/dist/consolidation-undo.js.map +1 -1
  178. package/dist/contradiction/index.js +6 -5
  179. package/dist/convergence-refresh.js +22 -21
  180. package/dist/corpus-watermark.js +22 -21
  181. package/dist/deep-recall-http-glue.js +11 -10
  182. package/dist/deep-recall.js +2 -2
  183. package/dist/embedding-fallback.js +4 -3
  184. package/dist/embedding-generation-lock.js +3 -2
  185. package/dist/entity-retrieval.js +20 -19
  186. package/dist/explicit-capture.js +8 -7
  187. package/dist/external-wiki-access.js +67 -65
  188. package/dist/extraction.js +25 -24
  189. package/dist/{forget-SZ2BXDGF.js → forget-OHAJ6PSU.js} +4 -3
  190. package/dist/{forget-SZ2BXDGF.js.map → forget-OHAJ6PSU.js.map} +1 -1
  191. package/dist/{graph-edge-decay-PVKDKLQK.js → graph-edge-decay-CZ3SYLM4.js} +7 -6
  192. package/dist/graph-jsonl.js +5 -4
  193. package/dist/graph-snapshot.js +5 -4
  194. package/dist/graph-write-lock.js +3 -2
  195. package/dist/graph.js +4 -3
  196. package/dist/harmonic-retrieval.d.ts.map +1 -1
  197. package/dist/harmonic-retrieval.js +22 -20
  198. package/dist/harmonic-source-lookup.d.ts +14 -0
  199. package/dist/harmonic-source-lookup.d.ts.map +1 -0
  200. package/dist/harmonic-source-lookup.js +22 -0
  201. package/dist/http-retry.d.ts.map +1 -1
  202. package/dist/http-retry.js +6 -8
  203. package/dist/http-retry.js.map +1 -1
  204. package/dist/index.js +144 -142
  205. package/dist/lcm/engine.js +2 -2
  206. package/dist/lcm/index.js +4 -4
  207. package/dist/location/index.js +23 -22
  208. package/dist/maintenance/memory-governance.js +20 -19
  209. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +20 -19
  210. package/dist/maintenance/rebuild-memory-projection-runner.js +22 -21
  211. package/dist/maintenance/rebuild-memory-projection.js +21 -20
  212. package/dist/memory-browse-operations.js +67 -65
  213. package/dist/memory-browse.js +8 -7
  214. package/dist/memory-projection-batch.d.ts +2 -0
  215. package/dist/memory-projection-batch.d.ts.map +1 -1
  216. package/dist/memory-projection-batch.js +4 -1
  217. package/dist/memory-subject.js +4 -3
  218. package/dist/namespaces/migrate.js +21 -20
  219. package/dist/namespaces/search.js +8 -7
  220. package/dist/namespaces/storage.js +20 -19
  221. package/dist/offline-sync-changeset-generations.js +6 -5
  222. package/dist/offline-sync-embedding-generation.js +5 -4
  223. package/dist/offline-sync-impression-drain.js +4 -3
  224. package/dist/offline-sync-snapshot-stream.js +8 -7
  225. package/dist/offline-sync.js +9 -8
  226. package/dist/operator-doctor-corpus.js +23 -22
  227. package/dist/operator-toolkit.js +40 -39
  228. package/dist/orchestration/maintenance.js +30 -29
  229. package/dist/orchestrator.js +133 -131
  230. package/dist/page-versioning.js +4 -3
  231. package/dist/procedural/procedure-miner.d.ts.map +1 -1
  232. package/dist/qmd-daemon-session.d.ts.map +1 -1
  233. package/dist/qmd-daemon-session.js +2 -1
  234. package/dist/qmd.d.ts.map +1 -1
  235. package/dist/qmd.js +7 -6
  236. package/dist/recall-navigation-operations.js +67 -65
  237. package/dist/recall-navigation.js +66 -64
  238. package/dist/recall-state-view-admission.js +8 -7
  239. package/dist/recall-state.js +3 -2
  240. package/dist/recall-why-service.js +8 -7
  241. package/dist/reconcile/manifest.js +4 -3
  242. package/dist/{resolution-TV3F7ZTH.js → resolution-E4GLHLY6.js} +7 -6
  243. package/dist/resolution-E4GLHLY6.js.map +1 -0
  244. package/dist/resume-bundles.js +29 -28
  245. package/dist/salvage-envelope.js +6 -5
  246. package/dist/search/factory.js +7 -6
  247. package/dist/search/index.js +9 -8
  248. package/dist/semantic-consolidation.js +21 -20
  249. package/dist/semantic-rule-promotion.js +20 -19
  250. package/dist/semantic-rule-verifier.js +20 -19
  251. package/dist/source-agent-qualifier.js +24 -23
  252. package/dist/standup/build.js +20 -19
  253. package/dist/storage.js +19 -18
  254. package/dist/subject-config.js +5 -4
  255. package/dist/summarizer.js +4 -3
  256. package/dist/summary-snapshot.js +3 -2
  257. package/dist/support-passport/index.js +69 -67
  258. package/dist/testing/orchestrator-lite.d.ts +1 -2
  259. package/dist/testing/orchestrator-lite.d.ts.map +1 -1
  260. package/dist/transfer/autodetect.js +1 -1
  261. package/dist/transfer/backup.js +1 -1
  262. package/dist/transfer/capsule-export.js +2 -2
  263. package/dist/transfer/capsule-import.js +5 -4
  264. package/dist/transfer/export-okf.js +20 -19
  265. package/dist/utils/serialize-mutations.d.ts.map +1 -1
  266. package/dist/utils/serialize-mutations.js +2 -1
  267. package/dist/utils/sleep.d.ts +3 -0
  268. package/dist/utils/sleep.d.ts.map +1 -0
  269. package/dist/verified-recall.js +20 -19
  270. package/dist/who-knows-cli.js +21 -20
  271. package/dist/who-knows.js +20 -19
  272. package/dist/write-envelope.js +5 -4
  273. package/package.json +2 -2
  274. package/src/access-idempotency.ts +1 -4
  275. package/src/harmonic-retrieval.ts +12 -64
  276. package/src/harmonic-source-lookup.test.ts +178 -0
  277. package/src/harmonic-source-lookup.ts +142 -0
  278. package/src/http-retry.ts +2 -6
  279. package/src/memory-projection-batch.test.ts +55 -0
  280. package/src/memory-projection-batch.ts +20 -0
  281. package/src/offline-sync-digest-cache.test.ts +45 -0
  282. package/src/orchestration/recall-internal.ts +12 -12
  283. package/src/procedural/procedure-miner.ts +1 -4
  284. package/src/qmd-daemon-session.ts +1 -4
  285. package/src/qmd.ts +0 -4
  286. package/src/recall-harmonic-qmd-ordering.test.ts +304 -0
  287. package/src/testing/orchestrator-lite.ts +2 -7
  288. package/src/utils/serialize-mutations.ts +1 -13
  289. package/src/utils/sleep.test.ts +32 -0
  290. package/src/utils/sleep.ts +5 -0
  291. package/dist/chunk-7PZHH4KC.js.map +0 -1
  292. package/dist/chunk-AJ6ORARY.js.map +0 -1
  293. package/dist/chunk-DTXN4NVD.js.map +0 -1
  294. package/dist/chunk-FFAZ2XFU.js.map +0 -1
  295. package/dist/chunk-IM2GO42H.js.map +0 -1
  296. package/dist/chunk-VFUEZZBS.js.map +0 -1
  297. package/dist/chunk-YJAOYEWI.js.map +0 -1
  298. /package/dist/{chunk-OZABSIOV.js.map → chunk-2AFHZTPI.js.map} +0 -0
  299. /package/dist/{chunk-UK5EH7AI.js.map → chunk-2CXQZXWM.js.map} +0 -0
  300. /package/dist/{chunk-D6M3VKMY.js.map → chunk-2K7D6EFT.js.map} +0 -0
  301. /package/dist/{chunk-RIEGCK2W.js.map → chunk-2KRNPFPK.js.map} +0 -0
  302. /package/dist/{chunk-N7QV3CMX.js.map → chunk-2NCBDGND.js.map} +0 -0
  303. /package/dist/{chunk-XQSJXNWC.js.map → chunk-3ENX2RB4.js.map} +0 -0
  304. /package/dist/{chunk-CLCMDKTB.js.map → chunk-3I3U6FFT.js.map} +0 -0
  305. /package/dist/{chunk-WWLAKRMX.js.map → chunk-3NFN4Y4P.js.map} +0 -0
  306. /package/dist/{chunk-I56MTWE7.js.map → chunk-3R6SLDTH.js.map} +0 -0
  307. /package/dist/{chunk-QEPL7KIZ.js.map → chunk-3VTNNO2B.js.map} +0 -0
  308. /package/dist/{chunk-QWUJWBZ5.js.map → chunk-4G4B3Z2B.js.map} +0 -0
  309. /package/dist/{chunk-R7QY5ZVB.js.map → chunk-4NDWE44P.js.map} +0 -0
  310. /package/dist/{chunk-KCCZFDJD.js.map → chunk-4OKPH6FG.js.map} +0 -0
  311. /package/dist/{chunk-I25RQA65.js.map → chunk-55ZVZBX4.js.map} +0 -0
  312. /package/dist/{chunk-ENNC3RZ6.js.map → chunk-5EOV7ANU.js.map} +0 -0
  313. /package/dist/{chunk-ANZXWOYD.js.map → chunk-5FNVK7MW.js.map} +0 -0
  314. /package/dist/{chunk-KSUOM3YU.js.map → chunk-5NOPZYNI.js.map} +0 -0
  315. /package/dist/{chunk-7LYRFI5A.js.map → chunk-5Q4NQNW7.js.map} +0 -0
  316. /package/dist/{chunk-L3PWXD73.js.map → chunk-6PHB45IU.js.map} +0 -0
  317. /package/dist/{chunk-CHDGJJV6.js.map → chunk-6VAHJ2F6.js.map} +0 -0
  318. /package/dist/{chunk-KQT4DRKF.js.map → chunk-76KHEHT2.js.map} +0 -0
  319. /package/dist/{chunk-SWRN6U7Q.js.map → chunk-7O252IE6.js.map} +0 -0
  320. /package/dist/{chunk-U6HWKOGD.js.map → chunk-7OAIOE5P.js.map} +0 -0
  321. /package/dist/{chunk-RSMIRLKM.js.map → chunk-7UX44C4N.js.map} +0 -0
  322. /package/dist/{chunk-DJMVSUPK.js.map → chunk-A6G7K273.js.map} +0 -0
  323. /package/dist/{chunk-VC4J4UTI.js.map → chunk-AAM66QCP.js.map} +0 -0
  324. /package/dist/{chunk-TZQOCQXB.js.map → chunk-AL6EHLB5.js.map} +0 -0
  325. /package/dist/{chunk-IJ4FEGZR.js.map → chunk-AMFCRZYB.js.map} +0 -0
  326. /package/dist/{chunk-4K2H4KTR.js.map → chunk-AV46CT77.js.map} +0 -0
  327. /package/dist/{chunk-VZBW6CDG.js.map → chunk-BOOFTFFE.js.map} +0 -0
  328. /package/dist/{chunk-2UF42WXV.js.map → chunk-BPY4RRTF.js.map} +0 -0
  329. /package/dist/{chunk-2U3R3DDH.js.map → chunk-BTJ6CAIA.js.map} +0 -0
  330. /package/dist/{chunk-GF4H3B3R.js.map → chunk-C3WJNRGR.js.map} +0 -0
  331. /package/dist/{chunk-SIYZDT2V.js.map → chunk-CBP4HWCL.js.map} +0 -0
  332. /package/dist/{chunk-GEGUBU3D.js.map → chunk-CSUAHUOH.js.map} +0 -0
  333. /package/dist/{chunk-BNMI3JBV.js.map → chunk-DXHVD4DS.js.map} +0 -0
  334. /package/dist/{chunk-GE6HETIF.js.map → chunk-E5274WUC.js.map} +0 -0
  335. /package/dist/{chunk-2COXDQ6C.js.map → chunk-E6KXJSMA.js.map} +0 -0
  336. /package/dist/{chunk-CCMXCZLT.js.map → chunk-FBVLTTVV.js.map} +0 -0
  337. /package/dist/{chunk-XVC7JU2N.js.map → chunk-FQD2KPQH.js.map} +0 -0
  338. /package/dist/{chunk-SNXBXYUE.js.map → chunk-GDI64ITR.js.map} +0 -0
  339. /package/dist/{chunk-MH2DXDN6.js.map → chunk-GSAZBZMA.js.map} +0 -0
  340. /package/dist/{chunk-MULNBSPP.js.map → chunk-HT2C4EXO.js.map} +0 -0
  341. /package/dist/{chunk-EMVJU7WC.js.map → chunk-HZVYDWUP.js.map} +0 -0
  342. /package/dist/{chunk-XPRAOTJY.js.map → chunk-IJWEXCWF.js.map} +0 -0
  343. /package/dist/{chunk-L2VS27PZ.js.map → chunk-IOM5QSNR.js.map} +0 -0
  344. /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  345. /package/dist/{chunk-TDMNADPI.js.map → chunk-JK3DYMOC.js.map} +0 -0
  346. /package/dist/{chunk-SZXPKUMN.js.map → chunk-JSIQSZXI.js.map} +0 -0
  347. /package/dist/{chunk-KQI2PKYP.js.map → chunk-JTUKDLAD.js.map} +0 -0
  348. /package/dist/{chunk-TL4PM7PC.js.map → chunk-K3DZ3G5I.js.map} +0 -0
  349. /package/dist/{chunk-WG4TMZJ2.js.map → chunk-KDYQYMJZ.js.map} +0 -0
  350. /package/dist/{chunk-N4PYB235.js.map → chunk-KI6UOSNR.js.map} +0 -0
  351. /package/dist/{chunk-FC6RCOIU.js.map → chunk-KRIEQCKE.js.map} +0 -0
  352. /package/dist/{chunk-EQUD7FP4.js.map → chunk-KYY4EACB.js.map} +0 -0
  353. /package/dist/{chunk-QMFKW4OU.js.map → chunk-L3Z4NXDO.js.map} +0 -0
  354. /package/dist/{chunk-KE5PWLI6.js.map → chunk-LOFVW6JA.js.map} +0 -0
  355. /package/dist/{chunk-46WM6JX2.js.map → chunk-LZKOVXMX.js.map} +0 -0
  356. /package/dist/{chunk-JMF5Q4JY.js.map → chunk-MAJ2OKE4.js.map} +0 -0
  357. /package/dist/{chunk-U6OXJQEH.js.map → chunk-MB5EJ2CT.js.map} +0 -0
  358. /package/dist/{chunk-VUEG3TZ4.js.map → chunk-MVRIW6MI.js.map} +0 -0
  359. /package/dist/{chunk-TGF43K66.js.map → chunk-MZBWIJJN.js.map} +0 -0
  360. /package/dist/{chunk-QGLEM46C.js.map → chunk-N44GZ73R.js.map} +0 -0
  361. /package/dist/{chunk-63UNVGZW.js.map → chunk-N6UMXWBA.js.map} +0 -0
  362. /package/dist/{chunk-FLV7M7CT.js.map → chunk-NAHUBSUF.js.map} +0 -0
  363. /package/dist/{chunk-S5TGRZWY.js.map → chunk-NXLQQ6WI.js.map} +0 -0
  364. /package/dist/{chunk-5AYUHSAU.js.map → chunk-OFCHT2TN.js.map} +0 -0
  365. /package/dist/{chunk-HRZZJ4XB.js.map → chunk-P2S6P7X6.js.map} +0 -0
  366. /package/dist/{chunk-OGVJXIHX.js.map → chunk-PBVNVKYN.js.map} +0 -0
  367. /package/dist/{chunk-2CP577K6.js.map → chunk-PPIASWWR.js.map} +0 -0
  368. /package/dist/{chunk-6C76FZRM.js.map → chunk-QFIPSKPC.js.map} +0 -0
  369. /package/dist/{chunk-Q562GF7J.js.map → chunk-QN77HA6P.js.map} +0 -0
  370. /package/dist/{chunk-MFZACYZ6.js.map → chunk-QUNDYIYZ.js.map} +0 -0
  371. /package/dist/{chunk-L34W4W4I.js.map → chunk-QW7G7PWN.js.map} +0 -0
  372. /package/dist/{chunk-W5XWHTDO.js.map → chunk-QZZPUREO.js.map} +0 -0
  373. /package/dist/{chunk-JA72X46J.js.map → chunk-R2AWYR4Q.js.map} +0 -0
  374. /package/dist/{chunk-YRULQW5J.js.map → chunk-RBJQYMMT.js.map} +0 -0
  375. /package/dist/{chunk-6KHF6PAB.js.map → chunk-RH6QEGCT.js.map} +0 -0
  376. /package/dist/{chunk-QRZMJ2WN.js.map → chunk-RNPJ4GQA.js.map} +0 -0
  377. /package/dist/{chunk-TRBLJU6Y.js.map → chunk-S4GUMZRB.js.map} +0 -0
  378. /package/dist/{chunk-MQNOIH2C.js.map → chunk-SQ2O52SU.js.map} +0 -0
  379. /package/dist/{chunk-EP5WXE2G.js.map → chunk-TCYLCPC6.js.map} +0 -0
  380. /package/dist/{chunk-PO7NXNGC.js.map → chunk-VFTK5WKI.js.map} +0 -0
  381. /package/dist/{chunk-JA54KIYD.js.map → chunk-VSHRMIJH.js.map} +0 -0
  382. /package/dist/{chunk-5BPXMAUP.js.map → chunk-VUQDJ3JB.js.map} +0 -0
  383. /package/dist/{chunk-7CXL25AA.js.map → chunk-W4RLOZOG.js.map} +0 -0
  384. /package/dist/{chunk-LHRQBMJN.js.map → chunk-WADSXS4K.js.map} +0 -0
  385. /package/dist/{chunk-Y7427SL7.js.map → chunk-WCGJK4NQ.js.map} +0 -0
  386. /package/dist/{chunk-37HCPM56.js.map → chunk-WJLGUY27.js.map} +0 -0
  387. /package/dist/{chunk-YGPXV546.js.map → chunk-WPFSZZ35.js.map} +0 -0
  388. /package/dist/{chunk-UXIZ5XN5.js.map → chunk-XLIK2VDE.js.map} +0 -0
  389. /package/dist/{chunk-64S6X4IU.js.map → chunk-XTN54NML.js.map} +0 -0
  390. /package/dist/{chunk-2UPTRDGM.js.map → chunk-Y6DZ33PA.js.map} +0 -0
  391. /package/dist/{chunk-4JNTGPBR.js.map → chunk-YAF3NRNC.js.map} +0 -0
  392. /package/dist/{chunk-IFCKHPY4.js.map → chunk-YDH2FSDI.js.map} +0 -0
  393. /package/dist/{chunk-L6GNS5GB.js.map → chunk-YS7SA4HD.js.map} +0 -0
  394. /package/dist/{chunk-EIFYYHAF.js.map → chunk-YYO447A7.js.map} +0 -0
  395. /package/dist/{chunk-75PT4N7Q.js.map → chunk-ZI7LMSNI.js.map} +0 -0
  396. /package/dist/{chunk-EUT2WCWS.js.map → chunk-ZQ3WU6JO.js.map} +0 -0
  397. /package/dist/{chunk-YJEUHGZZ.js.map → chunk-ZQYAE2C5.js.map} +0 -0
  398. /package/dist/{chunk-JYG2334B.js.map → chunk-ZSJGYC3C.js.map} +0 -0
  399. /package/dist/{graph-edge-decay-PVKDKLQK.js.map → graph-edge-decay-CZ3SYLM4.js.map} +0 -0
  400. /package/dist/{resolution-TV3F7ZTH.js.map → harmonic-source-lookup.js.map} +0 -0
@@ -0,0 +1,142 @@
1
+ import path from "node:path";
2
+ import { existsSync } from "node:fs";
3
+ import { mkdir, realpath } from "node:fs/promises";
4
+ import { throwIfAborted } from "./abort-error.js";
5
+ import { readJsonFile, writeJsonFileAtomic } from "./json-store.js";
6
+ import { readProjectedMemoryPaths } from "./memory-projection-batch.js";
7
+ import { SecureStoreLockedError } from "./secure-store/secure-fs.js";
8
+ import { isPathInsideStorageRoot, isSafeLegacyPathSegment } from "./storage-paths.js";
9
+ import { isRecord } from "./store-contract.js";
10
+ import type { StorageManager } from "./storage.js";
11
+ import type { MemoryFile } from "./types.js";
12
+ import { RECALL_FALLBACK_DIRS } from "./utils/category-dir.js";
13
+
14
+ const LOOKUP_TTL_MS = 10 * 60_000;
15
+ const MAX_CACHE_ENTRIES = 4096;
16
+ type PathEntry = { path: string | null; expiresAt: number };
17
+
18
+ /** Direct and cached probes must retain the walk's realpath containment check. */
19
+ export async function readHarmonicSourceMemory(
20
+ storage: StorageManager,
21
+ rootReal: string,
22
+ filePath: string,
23
+ abortSignal?: AbortSignal,
24
+ ): Promise<MemoryFile | null> {
25
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
26
+ if (!existsSync(filePath)) return null;
27
+ try {
28
+ if (!isPathInsideStorageRoot(rootReal, await realpath(filePath))) return null;
29
+ return await storage.readMemoryByPath(filePath);
30
+ } catch (err) {
31
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
32
+ if (err instanceof SecureStoreLockedError) throw err;
33
+ return null;
34
+ }
35
+ }
36
+
37
+ function isCorpusPath(memoryDir: string, filePath: string): boolean {
38
+ if (!isPathInsideStorageRoot(memoryDir, filePath)) return false;
39
+ const [dir] = path.relative(memoryDir, filePath).split(path.sep);
40
+ return dir === "cold" || RECALL_FALLBACK_DIRS.includes(dir);
41
+ }
42
+
43
+ /** A cache miss is not authoritative: unreadable/invalid cache state keeps the walk. */
44
+ async function readPathCache(
45
+ filePath: string, rebuiltAt: string, corpusVersion: string, nowMs: number,
46
+ ): Promise<Map<string, PathEntry>> {
47
+ try {
48
+ const raw = await readJsonFile(filePath);
49
+ if (!isRecord(raw) || raw.rebuiltAt !== rebuiltAt || raw.corpusVersion !== corpusVersion || !Array.isArray(raw.entries)) return new Map();
50
+ const entries = new Map<string, PathEntry>();
51
+ for (const row of raw.entries) {
52
+ if (!Array.isArray(row) || row.length !== 3) continue;
53
+ const [id, storedPath, expiresAt] = row;
54
+ if (typeof id !== "string" || (storedPath !== null && typeof storedPath !== "string")) continue;
55
+ if (typeof expiresAt !== "number" || !Number.isFinite(expiresAt) || expiresAt <= nowMs || expiresAt > nowMs + LOOKUP_TTL_MS) continue;
56
+ entries.set(id, { path: storedPath, expiresAt });
57
+ }
58
+ return entries;
59
+ } catch {
60
+ return new Map();
61
+ }
62
+ }
63
+
64
+ /** Resolve only unresolved ids; persist paths/absence, never memory content. */
65
+ export async function readUnresolvedHarmonicSources(options: {
66
+ storage: StorageManager;
67
+ rootReal: string;
68
+ rebuiltAt: string;
69
+ sourceMemoryIds: string[];
70
+ nowMs: number;
71
+ abortSignal?: AbortSignal;
72
+ }): Promise<Map<string, MemoryFile>> {
73
+ const { storage, rootReal, rebuiltAt, nowMs, abortSignal } = options;
74
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
75
+ const corpusVersion = storage.getCorpusScanVersion();
76
+ const stateDir = path.join(storage.dir, "state");
77
+ const cachePath = path.join(stateDir, "harmonic-source-paths.json");
78
+ const stateReal = await realpath(stateDir).catch(() => null);
79
+ const safeCache = stateReal !== null && isPathInsideStorageRoot(rootReal, stateReal);
80
+ const cache = safeCache ? await readPathCache(cachePath, rebuiltAt, corpusVersion, nowMs) : new Map<string, PathEntry>();
81
+ const found = new Map<string, MemoryFile>();
82
+ const pending = new Set<string>();
83
+ for (const id of options.sourceMemoryIds) {
84
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
85
+ const entry = cache.get(id);
86
+ if (entry?.path === null) continue;
87
+ if (entry?.path) {
88
+ const candidate = path.resolve(storage.dir, entry.path);
89
+ const memory = isCorpusPath(storage.dir, candidate)
90
+ ? await readHarmonicSourceMemory(storage, rootReal, candidate, abortSignal) : null;
91
+ if (memory?.frontmatter.id === id) {
92
+ found.set(id, memory);
93
+ continue;
94
+ }
95
+ }
96
+ pending.add(id);
97
+ }
98
+ if (pending.size === 0) return found;
99
+
100
+ // Opaque legacy ids previously used the full scan, including edited projected files.
101
+ const inspectProjected = [...pending].some((id) => !isSafeLegacyPathSegment(id));
102
+ const projectedPaths = readProjectedMemoryPaths(storage.dir);
103
+ const walked = [
104
+ ...(await storage.collectActiveMemoryPaths({ abortSignal, propagateReadErrors: true })),
105
+ ...(await storage.collectColdMemoryPaths({ abortSignal, propagateReadErrors: true })),
106
+ ];
107
+ for (const filePath of walked) {
108
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
109
+ // Existing projected files need no parse unless their filename names a wanted id.
110
+ // New/imported files must be keyed by frontmatter id, not their basename (#3188).
111
+ if (!inspectProjected && !pending.has(path.basename(filePath, ".md")) && projectedPaths?.has(filePath)) continue;
112
+ const memory = await readHarmonicSourceMemory(storage, rootReal, filePath, abortSignal);
113
+ if (!memory) continue;
114
+ const id = memory.frontmatter.id;
115
+ if (pending.has(id)) {
116
+ found.set(id, memory);
117
+ cache.set(id, { path: path.relative(storage.dir, filePath), expiresAt: nowMs + LOOKUP_TTL_MS });
118
+ }
119
+ }
120
+ for (const id of pending) {
121
+ if (!found.has(id)) cache.set(id, { path: null, expiresAt: nowMs + LOOKUP_TTL_MS });
122
+ }
123
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
124
+ // A concurrent mutation must not publish absence for a different corpus epoch.
125
+ if (storage.getCorpusScanVersion() === corpusVersion) {
126
+ try {
127
+ await mkdir(stateDir, { recursive: true });
128
+ if (isPathInsideStorageRoot(rootReal, await realpath(stateDir))) {
129
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
130
+ // ponytail: atomic last-writer-wins cache; contention can repeat a walk, not lose sources.
131
+ await writeJsonFileAtomic(cachePath, {
132
+ rebuiltAt, corpusVersion,
133
+ entries: [...cache].slice(-MAX_CACHE_ENTRIES).map(([id, entry]) => [id, entry.path, entry.expiresAt]),
134
+ });
135
+ }
136
+ } catch {
137
+ throwIfAborted(abortSignal, "harmonic retrieval aborted");
138
+ // Cache publication is optional; resolved memories remain usable on a read-only store.
139
+ }
140
+ }
141
+ return found;
142
+ }
package/src/http-retry.ts CHANGED
@@ -13,6 +13,8 @@
13
13
  * `@remnic/core/abort-error`) — the root index stays untouched.
14
14
  */
15
15
 
16
+ import { sleep as defaultSleep } from "./utils/sleep.js";
17
+
16
18
  export interface RetryingFetchOptions {
17
19
  /** Request init for every attempt. Ignored when `buildInit` is set. */
18
20
  init?: RequestInit;
@@ -70,12 +72,6 @@ const DEFAULT_MAX_RETRIES = 3;
70
72
  const DEFAULT_MAX_RETRY_DELAY_MS = 30_000;
71
73
  const DEFAULT_BACKOFF_BASE_MS = 1_000;
72
74
 
73
- function defaultSleep(ms: number): Promise<void> {
74
- const { promise, resolve } = Promise.withResolvers<void>();
75
- setTimeout(resolve, ms);
76
- return promise;
77
- }
78
-
79
75
  /**
80
76
  * Network/timeout failures wrap Node error text that can carry loader
81
77
  * paths or stack fragments; sync errors reach MCP clients verbatim, so
@@ -0,0 +1,55 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtemp, rm } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+ import { readProjectedMemoryStates } from "./memory-projection-batch.js";
7
+ import { getMemoryProjectionPath, readProjectedMemoryState } from "./memory-projection-store.js";
8
+ import { rebuildMemoryProjection } from "./maintenance/rebuild-memory-projection.js";
9
+ import { openBetterSqlite3 } from "./runtime/better-sqlite.js";
10
+ import { StorageManager } from "./storage.js";
11
+
12
+ test("projection batches return only requested rows and preserve completeness metadata", async () => {
13
+ const memoryDir = await mkdtemp(path.join(tmpdir(), "remnic-projection-batch-"));
14
+ try {
15
+ assert.equal(readProjectedMemoryStates(memoryDir, ["missing"]), null);
16
+ const storage = new StorageManager(memoryDir);
17
+ await storage.ensureDirectories();
18
+ const source = await storage.writeMemory("fact", "batch source payload", {
19
+ source: "test", tags: ["zeta", "alpha"], entityRef: "person:narwhal", confidence: 0.9,
20
+ });
21
+ const excluded = await storage.writeMemory("fact", "unrequested source payload", { source: "test" });
22
+ await rebuildMemoryProjection({ memoryDir, storage, dryRun: false });
23
+
24
+ const batch = readProjectedMemoryStates(memoryDir, new Set([source.id, "missing"]));
25
+ assert.ok(batch);
26
+ assert.deepEqual([...batch.states.keys()], [source.id]);
27
+ assert.equal(batch.states.has(excluded.id), false);
28
+ assert.deepEqual(batch.states.get(source.id), readProjectedMemoryState(memoryDir, source.id));
29
+ assert.deepEqual(batch.states.get(source.id)?.tags, ["alpha", "zeta"]);
30
+ assert.equal(batch.states.get(source.id)?.preview, "batch source payload");
31
+ assert.equal(batch.complete, true);
32
+ assert.ok(Number.isFinite(Date.parse(batch.rebuiltAt ?? "")));
33
+ assert.deepEqual(readProjectedMemoryStates(memoryDir, []), { ...batch, states: new Map() });
34
+
35
+ const db = openBetterSqlite3(getMemoryProjectionPath(memoryDir));
36
+ try {
37
+ const stamp = db.prepare("SELECT value FROM meta WHERE key = 'rebuiltAt'").get() as { value: string };
38
+ assert.equal(batch.rebuiltAt, stamp.value);
39
+ db.prepare("UPDATE meta SET value = 'false' WHERE key = 'complete'").run();
40
+ assert.equal(readProjectedMemoryStates(memoryDir, [source.id])?.complete, false);
41
+ db.prepare("DELETE FROM meta WHERE key IN ('complete', 'rebuiltAt')").run();
42
+ const legacy = readProjectedMemoryStates(memoryDir, [source.id]);
43
+ assert.ok(legacy);
44
+ assert.equal(legacy.complete, false);
45
+ assert.equal(legacy.rebuiltAt, null);
46
+ assert.deepEqual(legacy.states, batch.states);
47
+ db.exec("DROP TABLE memory_current");
48
+ assert.equal(readProjectedMemoryStates(memoryDir, [source.id]), null, "unreadable schema must fall back");
49
+ } finally {
50
+ db.close();
51
+ }
52
+ } finally {
53
+ await rm(memoryDir, { recursive: true, force: true });
54
+ }
55
+ });
@@ -1,4 +1,6 @@
1
+ import path from "node:path";
1
2
  import type { MemoryProjectionCurrentState } from "./types.js";
3
+ import { isRecord } from "./store-contract.js";
2
4
  import {
3
5
  memoryCurrentSelectExpressions,
4
6
  openProjectionReadonly,
@@ -80,3 +82,21 @@ export function readProjectedMemoryStates(
80
82
  db.close();
81
83
  }
82
84
  }
85
+
86
+ /** Path-only census used to avoid parsing already-projected files during a fallback lookup. */
87
+ export function readProjectedMemoryPaths(memoryDir: string): Set<string> | null {
88
+ const db = openProjectionReadonly(memoryDir);
89
+ if (!db) return null;
90
+ try {
91
+ const paths = new Set<string>();
92
+ for (const row of db.prepare("SELECT path_rel FROM memory_current").iterate()) {
93
+ const relative = isRecord(row) ? row.path_rel : undefined;
94
+ if (typeof relative === "string") paths.add(path.resolve(memoryDir, relative));
95
+ }
96
+ return paths;
97
+ } catch {
98
+ return null;
99
+ } finally {
100
+ db.close();
101
+ }
102
+ }
@@ -0,0 +1,45 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { parseOfflineSyncDigestCache } from "./offline-sync-digest-cache.js";
4
+
5
+ const digest = {
6
+ statBytes: 120, mtimeMs: 1_760_000_000_000, ctimeMs: 1_760_000_000_500,
7
+ encrypted: false, sha256: "a".repeat(64), bytes: 118,
8
+ };
9
+ const entry = { path: "facts/alpha.md", ...digest };
10
+ const cacheFile = (entries: unknown[]) => JSON.stringify({ version: 1, entries });
11
+
12
+ test("digest cache parses valid plaintext and encrypted entries without losing fields", () => {
13
+ const encrypted = { ...digest, encrypted: true, bytes: 0, sha256: "ABCDEF0123456789".repeat(4) };
14
+ assert.deepEqual([...parseOfflineSyncDigestCache(cacheFile([
15
+ entry, { path: "facts/beta.md", ...encrypted },
16
+ ]))], [[entry.path, digest], ["facts/beta.md", encrypted]]);
17
+ });
18
+
19
+ test("digest cache skips legacy records missing stat data but does not expire old timestamps", () => {
20
+ const old = { ...digest, mtimeMs: 1, ctimeMs: 1 };
21
+ const legacy = ["statBytes", "mtimeMs", "ctimeMs", "bytes", "sha256"].map((field) => ({
22
+ ...entry, [field]: undefined,
23
+ }));
24
+ // Freshness is checked against the file's stat by the caller, not by an age-based TTL here.
25
+ assert.deepEqual([...parseOfflineSyncDigestCache(cacheFile([
26
+ ...legacy, { path: "facts/old.md", ...old },
27
+ ]))], [["facts/old.md", old]]);
28
+ });
29
+
30
+ test("digest cache rejects garbage shapes and unsafe records while retaining valid siblings", () => {
31
+ for (const raw of ["null", "[]", "42", "{}", '{"entries":{}}']) {
32
+ assert.equal(parseOfflineSyncDigestCache(raw).size, 0);
33
+ }
34
+ const invalid = [
35
+ null, [], "garbage",
36
+ ...["", "..", "../escape.md", "/absolute.md"].map((path) => ({ ...entry, path })),
37
+ { ...entry, sha256: "z".repeat(64) }, { ...entry, sha256: "abc" },
38
+ { ...entry, statBytes: "120" }, { ...entry, mtimeMs: 1e400 },
39
+ { ...entry, ctimeMs: null }, { ...entry, bytes: "118" },
40
+ ];
41
+ assert.deepEqual([...parseOfflineSyncDigestCache(cacheFile([...invalid, entry]))], [[entry.path, digest]]);
42
+ for (const raw of ["", "{", '{"entries":[}']) {
43
+ assert.throws(() => parseOfflineSyncDigestCache(raw), SyntaxError);
44
+ }
45
+ });
@@ -3648,18 +3648,6 @@ export class RecallInternalCoordinator {
3648
3648
  this.deps.appendRecallSection(sectionBuckets, "trust-zones", trustZoneSection);
3649
3649
  }
3650
3650
 
3651
- const harmonicRetrievalSection = await awaitEnrichmentSection(
3652
- "harmonic",
3653
- harmonicRetrievalPromise,
3654
- );
3655
- if (harmonicRetrievalSection) {
3656
- this.deps.appendRecallSection(
3657
- sectionBuckets,
3658
- "harmonic-retrieval",
3659
- harmonicRetrievalSection,
3660
- );
3661
- }
3662
-
3663
3651
  if (verifiedRecallSection) {
3664
3652
  this.deps.appendRecallSection(
3665
3653
  sectionBuckets,
@@ -4780,6 +4768,18 @@ export class RecallInternalCoordinator {
4780
4768
  }
4781
4769
  }
4782
4770
  const phase2AfterQmdMs = Date.now() - recallStart;
4771
+
4772
+ const harmonicRetrievalSection = await awaitEnrichmentSection(
4773
+ "harmonic",
4774
+ harmonicRetrievalPromise,
4775
+ );
4776
+ if (harmonicRetrievalSection) {
4777
+ this.deps.appendRecallSection(
4778
+ sectionBuckets,
4779
+ "harmonic-retrieval",
4780
+ harmonicRetrievalSection,
4781
+ );
4782
+ }
4783
4783
  if (shouldPersistGraphSnapshot) {
4784
4784
  if (!graphSnapshotStatus) {
4785
4785
  graphSnapshotStatus = "skipped";
@@ -14,6 +14,7 @@ import { clusterByKey } from "./reinforcement-core.js";
14
14
  import { log } from "../logger.js";
15
15
  import { composeMemoryEnvelope, STRUCTURED_ATTRIBUTE_LIMITS } from "../write-envelope.js";
16
16
  import { isErrnoCode } from "../utils/errno.js";
17
+ import { sleep } from "../utils/sleep.js";
17
18
 
18
19
  /** Must match truncation on `procedure_cluster` structured attribute (dedupe + storage). */
19
20
  const PROCEDURE_CLUSTER_ATTR_MAX = 500;
@@ -51,10 +52,6 @@ function clusterKeyHash(cluster: string): string {
51
52
  return createHash("sha256").update(cluster).digest("hex");
52
53
  }
53
54
 
54
- function sleep(ms: number): Promise<void> {
55
- return new Promise((resolve) => setTimeout(resolve, ms));
56
- }
57
-
58
55
  async function acquireClusterWriteLock(memoryDir: string, clusterHash: string): Promise<() => Promise<void>> {
59
56
  const lockRoot = path.join(path.resolve(memoryDir), "state", "procedure-miner-locks");
60
57
  const lockDir = path.join(lockRoot, `${clusterHash}.lock`);
@@ -2,6 +2,7 @@ import { abortError, throwIfAborted } from "./abort-error.js";
2
2
  import { log } from "./logger.js";
3
3
  import { type CommandChildProcess, launchProcess } from "./runtime/child-process.js";
4
4
  import { mergeEnv } from "./runtime/env.js";
5
+ import { sleep } from "./utils/sleep.js";
5
6
 
6
7
  export type QmdRuntimeEnv = Record<string, string | undefined>;
7
8
 
@@ -20,10 +21,6 @@ type PendingRequest = {
20
21
 
21
22
  let nextJsonRpcId = 1;
22
23
 
23
- function sleep(ms: number): Promise<void> {
24
- return new Promise((resolve) => setTimeout(resolve, ms));
25
- }
26
-
27
24
  /**
28
25
  * Drop C0 controls and one ANSI CSI sequence. Char scan on purpose:
29
26
  * the regex-safety ratchet flags new regular expressions on changed lines.
package/src/qmd.ts CHANGED
@@ -218,10 +218,6 @@ function getGlobalQmdState(): QmdGlobalState {
218
218
  return state;
219
219
  }
220
220
 
221
- function sleep(ms: number): Promise<void> {
222
- return new Promise((r) => setTimeout(r, ms));
223
- }
224
-
225
221
  function errorMessage(err: unknown): string {
226
222
  if (typeof err === "string") return err;
227
223
  if (err instanceof Error) return err.message;