@remnic/core 9.69.102 → 9.69.104

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 (366) hide show
  1. package/dist/access-admin-ops-surface.js +53 -52
  2. package/dist/access-authorization-probe.js +54 -53
  3. package/dist/access-boundary.js +53 -52
  4. package/dist/access-cli.js +153 -150
  5. package/dist/access-cli.js.map +1 -1
  6. package/dist/access-extraction-force-flush.js +53 -52
  7. package/dist/access-http-briefing.js +54 -53
  8. package/dist/access-http-query.js +55 -54
  9. package/dist/access-http.js +77 -76
  10. package/dist/access-identity-continuity-surface.js +53 -52
  11. package/dist/access-lcm-surface.js +53 -52
  12. package/dist/access-mcp.js +66 -65
  13. package/dist/access-namespace-preflight.js +53 -52
  14. package/dist/access-observe-write-category.js +9 -9
  15. package/dist/access-observe-write-surface.js +53 -52
  16. package/dist/access-offline-manifest.js +6 -6
  17. package/dist/access-operations-batch.js +57 -56
  18. package/dist/access-operations.js +64 -63
  19. package/dist/access-recall-concurrency.js +53 -52
  20. package/dist/access-recall-response.js +53 -52
  21. package/dist/access-recall-surface.js +53 -52
  22. package/dist/access-schema.js +8 -8
  23. package/dist/access-service.js +53 -52
  24. package/dist/access-surface-catalog.js +55 -54
  25. package/dist/access-surface-catalog.js.map +1 -1
  26. package/dist/active-recall.js +21 -20
  27. package/dist/active-recall.js.map +1 -1
  28. package/dist/adapters/index.js +4 -4
  29. package/dist/adapters/registry.js +2 -2
  30. package/dist/briefing.js +14 -13
  31. package/dist/buffer.js +5 -5
  32. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  33. package/dist/{capsule-merge-ZCXUPLNJ.js → capsule-merge-42GJGDUC.js} +4 -3
  34. package/dist/{capsule-merge-ZCXUPLNJ.js.map → capsule-merge-42GJGDUC.js.map} +1 -1
  35. package/dist/causal-behavior.js +2 -2
  36. package/dist/causal-chain.js +2 -2
  37. package/dist/causal-consolidation.js +17 -16
  38. package/dist/causal-consolidation.js.map +1 -1
  39. package/dist/causal-retrieval.js +2 -2
  40. package/dist/causal-trajectory-graph.js +3 -3
  41. package/dist/causal-trajectory.js +1 -1
  42. package/dist/{chunk-47LTKAGL.js → chunk-2COXDQ6C.js} +21 -6
  43. package/dist/chunk-2COXDQ6C.js.map +1 -0
  44. package/dist/{chunk-IOYY6ROU.js → chunk-2MMBJE53.js} +7 -7
  45. package/dist/{chunk-QSXEQPC4.js → chunk-2OFDC3AK.js} +2 -2
  46. package/dist/{chunk-4MP2Q2EI.js → chunk-2TCNEJ36.js} +4 -4
  47. package/dist/{chunk-5FAGCOZD.js → chunk-2U3R3DDH.js} +9 -9
  48. package/dist/{chunk-SCXURCVT.js → chunk-2UPTRDGM.js} +3 -3
  49. package/dist/{chunk-XVZA6VXC.js → chunk-3SL52JKD.js} +4 -4
  50. package/dist/{chunk-SBOCJ47I.js → chunk-5R4YPRAR.js} +19 -6
  51. package/dist/chunk-5R4YPRAR.js.map +1 -0
  52. package/dist/{chunk-ANPRNTPT.js → chunk-63LFM77Z.js} +15 -2
  53. package/dist/chunk-63LFM77Z.js.map +1 -0
  54. package/dist/{chunk-DINOVGA5.js → chunk-6WRHNA4I.js} +48 -48
  55. package/dist/chunk-6WRHNA4I.js.map +1 -0
  56. package/dist/{chunk-DSPWVQZ6.js → chunk-73R4HOOK.js} +3 -3
  57. package/dist/chunk-7CT3AI52.js +84 -0
  58. package/dist/chunk-7CT3AI52.js.map +1 -0
  59. package/dist/{chunk-PHBH74Q6.js → chunk-7NBUE5VY.js} +2 -2
  60. package/dist/{chunk-S533KGX6.js → chunk-7X7A7KVN.js} +2 -2
  61. package/dist/{chunk-XEATJBNB.js → chunk-7YQR6XHY.js} +71 -71
  62. package/dist/{chunk-F5MINS3R.js → chunk-A6WNTVA7.js} +3 -3
  63. package/dist/{chunk-F5MINS3R.js.map → chunk-A6WNTVA7.js.map} +1 -1
  64. package/dist/{chunk-533RHNHB.js → chunk-ATFFWIKL.js} +2 -2
  65. package/dist/{chunk-QCYUIZK2.js → chunk-AU43D3IT.js} +7 -7
  66. package/dist/{chunk-JZ66PN72.js → chunk-AWSP3WNM.js} +2 -2
  67. package/dist/{chunk-IY47KPML.js → chunk-B3OFQP5Y.js} +6 -6
  68. package/dist/{chunk-4DXNOVNW.js → chunk-B454SHPU.js} +6 -6
  69. package/dist/{chunk-3LMOJXZR.js → chunk-BKVCTTEN.js} +2 -2
  70. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  71. package/dist/{chunk-CZN53OT5.js → chunk-CGBE3N7T.js} +2 -2
  72. package/dist/{chunk-HWLIMQE2.js → chunk-CHDGJJV6.js} +2 -2
  73. package/dist/{chunk-UYPQOASU.js → chunk-CNBGAFDY.js} +2 -2
  74. package/dist/{chunk-JTC3PBNH.js → chunk-DB6XFMOF.js} +3 -3
  75. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  76. package/dist/{chunk-UFIZRMQZ.js → chunk-E4XLFYHV.js} +61 -29
  77. package/dist/chunk-E4XLFYHV.js.map +1 -0
  78. package/dist/{chunk-4OXXDL3X.js → chunk-EWWK65CI.js} +2 -2
  79. package/dist/{chunk-DFPG47ET.js → chunk-EZ3F4YIN.js} +11 -11
  80. package/dist/{chunk-V3I4NLZP.js → chunk-FYX2LXIX.js} +2 -2
  81. package/dist/{chunk-PNVOKGAX.js → chunk-G5I5ZT6O.js} +2 -2
  82. package/dist/{chunk-7Z2UKRNJ.js → chunk-GQ6ZF4LD.js} +2 -2
  83. package/dist/{chunk-PEZAHDDU.js → chunk-GZ2KV2RO.js} +5 -5
  84. package/dist/chunk-H6Z3RNW3.js +330 -0
  85. package/dist/chunk-H6Z3RNW3.js.map +1 -0
  86. package/dist/{chunk-645WOU5I.js → chunk-H7BZBSP6.js} +4 -4
  87. package/dist/{chunk-AXHU56C3.js → chunk-HWGFTTPS.js} +2 -2
  88. package/dist/{chunk-2SGLMP2E.js → chunk-IDSZNHIP.js} +2 -2
  89. package/dist/{chunk-LO4UKPKX.js → chunk-IFCKHPY4.js} +2 -2
  90. package/dist/{chunk-ZHXSOMYH.js → chunk-IOMLGJHG.js} +4 -4
  91. package/dist/{chunk-YRULQW5J.js → chunk-ISX7GVZE.js} +4 -4
  92. package/dist/{chunk-5PHZSD75.js → chunk-J3ZJBX7I.js} +2 -2
  93. package/dist/{chunk-X5TAWDRO.js → chunk-JC7QQ2DJ.js} +2 -2
  94. package/dist/{chunk-RFQT7IZO.js → chunk-JRDL3FGM.js} +3 -3
  95. package/dist/{chunk-OGZC2WUX.js → chunk-JWFTPRYD.js} +2 -2
  96. package/dist/{chunk-7OA4JWP5.js → chunk-KFHEZJQZ.js} +2 -2
  97. package/dist/{chunk-P3WRFSYF.js → chunk-KMN2JE4D.js} +2 -2
  98. package/dist/{chunk-GNBZB43J.js → chunk-KV7LFOPF.js} +2 -2
  99. package/dist/{chunk-L6YCGS7I.js → chunk-KYUVFCT2.js} +2 -2
  100. package/dist/{chunk-5BVL2XUD.js → chunk-LHDSCWDK.js} +17 -17
  101. package/dist/{chunk-SF7CWSR6.js → chunk-LXJZUNLX.js} +2 -2
  102. package/dist/{chunk-XCB6QDL6.js → chunk-M5GVCJSJ.js} +8 -2
  103. package/dist/chunk-M5GVCJSJ.js.map +1 -0
  104. package/dist/{chunk-DGS34QSY.js → chunk-MFZACYZ6.js} +2 -2
  105. package/dist/{chunk-PYYQCHJC.js → chunk-MZOQ26LH.js} +2 -2
  106. package/dist/{chunk-R2TVWQLR.js → chunk-NT2Q6AHC.js} +2 -2
  107. package/dist/{chunk-ABGM2BN4.js → chunk-O43AAJFQ.js} +2 -2
  108. package/dist/{chunk-G3BW6SDE.js → chunk-OFGTRDWX.js} +3 -3
  109. package/dist/{chunk-6Z263Z3E.js → chunk-OWV6LKNZ.js} +2 -2
  110. package/dist/{chunk-HIHN4XHL.js → chunk-PQ7EB5AD.js} +3 -3
  111. package/dist/{chunk-VVYLVE6R.js → chunk-PQKZLBCJ.js} +1 -1
  112. package/dist/{chunk-OFFW73OZ.js → chunk-PRNR47DI.js} +2 -2
  113. package/dist/{chunk-UL7KDVLC.js → chunk-PZ2QQULY.js} +11 -11
  114. package/dist/{chunk-55NZVUNI.js → chunk-QAIVTLL2.js} +3 -3
  115. package/dist/{chunk-M7T2NKET.js → chunk-QKCGOECM.js} +2 -2
  116. package/dist/{chunk-ARY6O3JN.js → chunk-QUNCLKHM.js} +2 -2
  117. package/dist/{chunk-Z3O53WZR.js → chunk-QWUJWBZ5.js} +2 -2
  118. package/dist/{chunk-RZXFXKWY.js → chunk-QX3K3INR.js} +2 -2
  119. package/dist/{chunk-HFOY2SBG.js → chunk-RYN4AIRM.js} +7 -5
  120. package/dist/chunk-RYN4AIRM.js.map +1 -0
  121. package/dist/{chunk-4LNCLZNK.js → chunk-S2GR3T7W.js} +2 -2
  122. package/dist/{chunk-VPOAMPDD.js → chunk-SFDBLCZV.js} +59 -59
  123. package/dist/{chunk-2IWBHZ3H.js → chunk-SIGDETMB.js} +2 -2
  124. package/dist/chunk-SP4DB6SX.js +19 -0
  125. package/dist/chunk-SP4DB6SX.js.map +1 -0
  126. package/dist/{chunk-DBWNTLLI.js → chunk-STQC2FYQ.js} +6 -6
  127. package/dist/{chunk-S5R77WHV.js → chunk-SWXPR5SE.js} +2 -2
  128. package/dist/{chunk-3DNTFZAT.js → chunk-T32YYUT2.js} +2 -2
  129. package/dist/{chunk-W5JQSVPZ.js → chunk-T6RQNV7E.js} +2 -2
  130. package/dist/{chunk-O23QMYN4.js → chunk-TRN56SPQ.js} +2 -2
  131. package/dist/{chunk-NM3BT2OH.js → chunk-TXTRHF3B.js} +2 -2
  132. package/dist/{chunk-7AUIGOH4.js → chunk-VDVHIRCK.js} +2 -2
  133. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  134. package/dist/{chunk-ZGYLPCWN.js → chunk-VO2BNAA2.js} +3 -3
  135. package/dist/{chunk-WVEECBCG.js → chunk-VV2MVHCJ.js} +2 -2
  136. package/dist/{chunk-HVDEKJJR.js → chunk-VYIBRCVW.js} +70 -61
  137. package/dist/chunk-VYIBRCVW.js.map +1 -0
  138. package/dist/{chunk-B3O3IRZN.js → chunk-VZBW6CDG.js} +1 -1
  139. package/dist/{chunk-JPKK466T.js → chunk-W5XWHTDO.js} +2 -2
  140. package/dist/{chunk-CYG3K2T2.js → chunk-WR66CTVU.js} +6 -6
  141. package/dist/{chunk-JNAOTN7B.js → chunk-XLWMNDQR.js} +4 -4
  142. package/dist/chunk-XLWMNDQR.js.map +1 -0
  143. package/dist/{chunk-RP7RSENW.js → chunk-XQWKB6PY.js} +2 -2
  144. package/dist/{chunk-64S6X4IU.js → chunk-XTN54NML.js} +4 -4
  145. package/dist/{chunk-UCPGOUDZ.js → chunk-Y57GJDG5.js} +108 -3
  146. package/dist/chunk-Y57GJDG5.js.map +1 -0
  147. package/dist/{chunk-KYLYXGKD.js → chunk-YI6XIFQV.js} +2 -2
  148. package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
  149. package/dist/{chunk-Y7427SL7.js → chunk-Z6EZCN6Z.js} +10 -10
  150. package/dist/{chunk-5K2ALMSZ.js → chunk-ZRUC7FD3.js} +2 -2
  151. package/dist/cli.js +103 -102
  152. package/dist/coding/export-okf-codegraph.js +13 -12
  153. package/dist/coding/export-okf-codegraph.js.map +1 -1
  154. package/dist/coding/pre-action-gate.js +2 -2
  155. package/dist/compounding/engine.js +14 -13
  156. package/dist/config.js +21 -20
  157. package/dist/connectors/codex-materialize-runner.js +14 -13
  158. package/dist/connectors/index.js +14 -13
  159. package/dist/consolidation-provenance-check.js +4 -3
  160. package/dist/consolidation-undo.js +3 -2
  161. package/dist/consolidation-undo.js.map +1 -1
  162. package/dist/contradiction/index.js +3 -2
  163. package/dist/convergence-refresh.js +16 -15
  164. package/dist/corpus-watermark.js +16 -15
  165. package/dist/dashboard-runtime.js +2 -2
  166. package/dist/deep-recall-http-glue.js +9 -9
  167. package/dist/deep-recall.js +2 -2
  168. package/dist/embedding-fallback.d.ts +2 -1
  169. package/dist/embedding-fallback.d.ts.map +1 -1
  170. package/dist/embedding-fallback.js +2 -2
  171. package/dist/embedding-index-storage.d.ts +28 -1
  172. package/dist/embedding-index-storage.d.ts.map +1 -1
  173. package/dist/embedding-index-storage.js +1 -1
  174. package/dist/entity-mention-carry.d.ts +16 -0
  175. package/dist/entity-mention-carry.d.ts.map +1 -0
  176. package/dist/entity-mention-carry.js +8 -0
  177. package/dist/entity-mention-epoch.d.ts +22 -0
  178. package/dist/entity-mention-epoch.d.ts.map +1 -0
  179. package/dist/entity-mention-epoch.js +8 -0
  180. package/dist/entity-mention-index-cache.d.ts +28 -0
  181. package/dist/entity-mention-index-cache.d.ts.map +1 -0
  182. package/dist/entity-mention-index-cache.js +29 -0
  183. package/dist/entity-mention-index-cache.js.map +1 -0
  184. package/dist/entity-retrieval.d.ts.map +1 -1
  185. package/dist/entity-retrieval.js +18 -15
  186. package/dist/event-order-recall.js +2 -2
  187. package/dist/external-wiki-access.js +54 -53
  188. package/dist/extraction-span-materialize.js +2 -2
  189. package/dist/extraction.js +21 -20
  190. package/dist/{graph-edge-decay-MKIRZ762.js → graph-edge-decay-PVKDKLQK.js} +6 -6
  191. package/dist/graph-edge-decay-PVKDKLQK.js.map +1 -0
  192. package/dist/graph-jsonl.js +4 -4
  193. package/dist/graph-snapshot.js +4 -4
  194. package/dist/graph.js +5 -5
  195. package/dist/harmonic-retrieval.js +1 -1
  196. package/dist/index.js +187 -184
  197. package/dist/lcm/engine.js +4 -4
  198. package/dist/lcm/index.js +13 -13
  199. package/dist/location/index.js +16 -15
  200. package/dist/maintenance/memory-governance.js +14 -13
  201. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +14 -13
  202. package/dist/maintenance/rebuild-memory-projection.js +15 -14
  203. package/dist/memory-browse-operations.js +54 -53
  204. package/dist/memory-browse.js +5 -5
  205. package/dist/memory-corpus-version.d.ts +8 -3
  206. package/dist/memory-corpus-version.d.ts.map +1 -1
  207. package/dist/memory-corpus-version.js +2 -1
  208. package/dist/namespaces/migrate.js +15 -14
  209. package/dist/namespaces/search.js +7 -7
  210. package/dist/namespaces/storage.js +14 -13
  211. package/dist/offline-sync-changeset-generations.js +4 -4
  212. package/dist/offline-sync-embedding-generation.js +3 -3
  213. package/dist/offline-sync-exclude-globs.d.ts +8 -0
  214. package/dist/offline-sync-exclude-globs.d.ts.map +1 -1
  215. package/dist/offline-sync-exclude-globs.js +3 -1
  216. package/dist/offline-sync-snapshot-stream.js +6 -6
  217. package/dist/offline-sync.d.ts.map +1 -1
  218. package/dist/offline-sync.js +9 -9
  219. package/dist/operator-doctor-corpus.js +17 -16
  220. package/dist/operator-toolkit.js +34 -33
  221. package/dist/orchestration/maintenance.js +22 -21
  222. package/dist/orchestrator.js +153 -150
  223. package/dist/page-versioning.js +3 -2
  224. package/dist/preferences/preference-drift.d.ts.map +1 -1
  225. package/dist/procedural/library-maintenance.d.ts.map +1 -1
  226. package/dist/qmd.js +4 -4
  227. package/dist/recall-navigation-operations.js +54 -53
  228. package/dist/recall-navigation.js +53 -52
  229. package/dist/recall-state-view-admission.js +5 -5
  230. package/dist/recall-why-service.js +5 -5
  231. package/dist/{resolution-BROE3TRO.js → resolution-RSG4HZTL.js} +4 -3
  232. package/dist/resolution-RSG4HZTL.js.map +1 -0
  233. package/dist/resume-bundles.js +22 -21
  234. package/dist/search/factory.js +6 -6
  235. package/dist/search/index.js +12 -12
  236. package/dist/semantic-consolidation.js +15 -14
  237. package/dist/semantic-rule-promotion.js +14 -13
  238. package/dist/semantic-rule-verifier.js +14 -13
  239. package/dist/source-agent-qualifier.js +17 -16
  240. package/dist/standup/build.js +14 -13
  241. package/dist/storage/entity-mention-frontmatter-hold.d.ts +14 -0
  242. package/dist/storage/entity-mention-frontmatter-hold.d.ts.map +1 -0
  243. package/dist/storage.d.ts +13 -9
  244. package/dist/storage.d.ts.map +1 -1
  245. package/dist/storage.js +13 -12
  246. package/dist/support-passport/index.js +56 -55
  247. package/dist/transfer/backup.js +2 -2
  248. package/dist/transfer/capsule-export.js +2 -2
  249. package/dist/transfer/capsule-import.js +5 -4
  250. package/dist/transfer/export-okf.js +14 -13
  251. package/dist/verified-recall.js +14 -13
  252. package/dist/who-knows-cli.js +15 -14
  253. package/dist/who-knows.js +14 -13
  254. package/package.json +2 -2
  255. package/src/embedding-fallback-cross-process.test.ts +533 -0
  256. package/src/embedding-fallback.ts +19 -7
  257. package/src/embedding-index-storage.test.ts +482 -2
  258. package/src/embedding-index-storage.ts +131 -2
  259. package/src/entity-mention-carry.ts +31 -0
  260. package/src/entity-mention-epoch.ts +120 -0
  261. package/src/entity-mention-index-cache.ts +443 -0
  262. package/src/entity-retrieval.ts +72 -71
  263. package/src/maintenance/rebuild-memory-projection.ts +1 -1
  264. package/src/memory-corpus-version.ts +13 -3
  265. package/src/offline-sync-exclude-globs.ts +23 -0
  266. package/src/offline-sync.test.ts +325 -0
  267. package/src/offline-sync.ts +17 -1
  268. package/src/preferences/preference-drift.ts +5 -3
  269. package/src/procedural/library-maintenance.ts +4 -3
  270. package/src/semantic-rule-promotion.ts +1 -1
  271. package/src/storage/entity-mention-frontmatter-hold.ts +44 -0
  272. package/src/storage.ts +40 -38
  273. package/dist/chunk-47LTKAGL.js.map +0 -1
  274. package/dist/chunk-ANPRNTPT.js.map +0 -1
  275. package/dist/chunk-DINOVGA5.js.map +0 -1
  276. package/dist/chunk-HFOY2SBG.js.map +0 -1
  277. package/dist/chunk-HVDEKJJR.js.map +0 -1
  278. package/dist/chunk-JNAOTN7B.js.map +0 -1
  279. package/dist/chunk-SBOCJ47I.js.map +0 -1
  280. package/dist/chunk-UCPGOUDZ.js.map +0 -1
  281. package/dist/chunk-UFIZRMQZ.js.map +0 -1
  282. package/dist/chunk-XCB6QDL6.js.map +0 -1
  283. /package/dist/{capsule-crypto-7FJQINUR.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  284. /package/dist/{chunk-IOYY6ROU.js.map → chunk-2MMBJE53.js.map} +0 -0
  285. /package/dist/{chunk-QSXEQPC4.js.map → chunk-2OFDC3AK.js.map} +0 -0
  286. /package/dist/{chunk-4MP2Q2EI.js.map → chunk-2TCNEJ36.js.map} +0 -0
  287. /package/dist/{chunk-5FAGCOZD.js.map → chunk-2U3R3DDH.js.map} +0 -0
  288. /package/dist/{chunk-SCXURCVT.js.map → chunk-2UPTRDGM.js.map} +0 -0
  289. /package/dist/{chunk-XVZA6VXC.js.map → chunk-3SL52JKD.js.map} +0 -0
  290. /package/dist/{chunk-DSPWVQZ6.js.map → chunk-73R4HOOK.js.map} +0 -0
  291. /package/dist/{chunk-PHBH74Q6.js.map → chunk-7NBUE5VY.js.map} +0 -0
  292. /package/dist/{chunk-S533KGX6.js.map → chunk-7X7A7KVN.js.map} +0 -0
  293. /package/dist/{chunk-XEATJBNB.js.map → chunk-7YQR6XHY.js.map} +0 -0
  294. /package/dist/{chunk-533RHNHB.js.map → chunk-ATFFWIKL.js.map} +0 -0
  295. /package/dist/{chunk-QCYUIZK2.js.map → chunk-AU43D3IT.js.map} +0 -0
  296. /package/dist/{chunk-JZ66PN72.js.map → chunk-AWSP3WNM.js.map} +0 -0
  297. /package/dist/{chunk-IY47KPML.js.map → chunk-B3OFQP5Y.js.map} +0 -0
  298. /package/dist/{chunk-4DXNOVNW.js.map → chunk-B454SHPU.js.map} +0 -0
  299. /package/dist/{chunk-3LMOJXZR.js.map → chunk-BKVCTTEN.js.map} +0 -0
  300. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  301. /package/dist/{chunk-CZN53OT5.js.map → chunk-CGBE3N7T.js.map} +0 -0
  302. /package/dist/{chunk-HWLIMQE2.js.map → chunk-CHDGJJV6.js.map} +0 -0
  303. /package/dist/{chunk-UYPQOASU.js.map → chunk-CNBGAFDY.js.map} +0 -0
  304. /package/dist/{chunk-JTC3PBNH.js.map → chunk-DB6XFMOF.js.map} +0 -0
  305. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  306. /package/dist/{chunk-4OXXDL3X.js.map → chunk-EWWK65CI.js.map} +0 -0
  307. /package/dist/{chunk-DFPG47ET.js.map → chunk-EZ3F4YIN.js.map} +0 -0
  308. /package/dist/{chunk-V3I4NLZP.js.map → chunk-FYX2LXIX.js.map} +0 -0
  309. /package/dist/{chunk-PNVOKGAX.js.map → chunk-G5I5ZT6O.js.map} +0 -0
  310. /package/dist/{chunk-7Z2UKRNJ.js.map → chunk-GQ6ZF4LD.js.map} +0 -0
  311. /package/dist/{chunk-PEZAHDDU.js.map → chunk-GZ2KV2RO.js.map} +0 -0
  312. /package/dist/{chunk-645WOU5I.js.map → chunk-H7BZBSP6.js.map} +0 -0
  313. /package/dist/{chunk-AXHU56C3.js.map → chunk-HWGFTTPS.js.map} +0 -0
  314. /package/dist/{chunk-2SGLMP2E.js.map → chunk-IDSZNHIP.js.map} +0 -0
  315. /package/dist/{chunk-LO4UKPKX.js.map → chunk-IFCKHPY4.js.map} +0 -0
  316. /package/dist/{chunk-ZHXSOMYH.js.map → chunk-IOMLGJHG.js.map} +0 -0
  317. /package/dist/{chunk-YRULQW5J.js.map → chunk-ISX7GVZE.js.map} +0 -0
  318. /package/dist/{chunk-5PHZSD75.js.map → chunk-J3ZJBX7I.js.map} +0 -0
  319. /package/dist/{chunk-X5TAWDRO.js.map → chunk-JC7QQ2DJ.js.map} +0 -0
  320. /package/dist/{chunk-RFQT7IZO.js.map → chunk-JRDL3FGM.js.map} +0 -0
  321. /package/dist/{chunk-OGZC2WUX.js.map → chunk-JWFTPRYD.js.map} +0 -0
  322. /package/dist/{chunk-7OA4JWP5.js.map → chunk-KFHEZJQZ.js.map} +0 -0
  323. /package/dist/{chunk-P3WRFSYF.js.map → chunk-KMN2JE4D.js.map} +0 -0
  324. /package/dist/{chunk-GNBZB43J.js.map → chunk-KV7LFOPF.js.map} +0 -0
  325. /package/dist/{chunk-L6YCGS7I.js.map → chunk-KYUVFCT2.js.map} +0 -0
  326. /package/dist/{chunk-5BVL2XUD.js.map → chunk-LHDSCWDK.js.map} +0 -0
  327. /package/dist/{chunk-SF7CWSR6.js.map → chunk-LXJZUNLX.js.map} +0 -0
  328. /package/dist/{chunk-DGS34QSY.js.map → chunk-MFZACYZ6.js.map} +0 -0
  329. /package/dist/{chunk-PYYQCHJC.js.map → chunk-MZOQ26LH.js.map} +0 -0
  330. /package/dist/{chunk-R2TVWQLR.js.map → chunk-NT2Q6AHC.js.map} +0 -0
  331. /package/dist/{chunk-ABGM2BN4.js.map → chunk-O43AAJFQ.js.map} +0 -0
  332. /package/dist/{chunk-G3BW6SDE.js.map → chunk-OFGTRDWX.js.map} +0 -0
  333. /package/dist/{chunk-6Z263Z3E.js.map → chunk-OWV6LKNZ.js.map} +0 -0
  334. /package/dist/{chunk-HIHN4XHL.js.map → chunk-PQ7EB5AD.js.map} +0 -0
  335. /package/dist/{chunk-VVYLVE6R.js.map → chunk-PQKZLBCJ.js.map} +0 -0
  336. /package/dist/{chunk-OFFW73OZ.js.map → chunk-PRNR47DI.js.map} +0 -0
  337. /package/dist/{chunk-UL7KDVLC.js.map → chunk-PZ2QQULY.js.map} +0 -0
  338. /package/dist/{chunk-55NZVUNI.js.map → chunk-QAIVTLL2.js.map} +0 -0
  339. /package/dist/{chunk-M7T2NKET.js.map → chunk-QKCGOECM.js.map} +0 -0
  340. /package/dist/{chunk-ARY6O3JN.js.map → chunk-QUNCLKHM.js.map} +0 -0
  341. /package/dist/{chunk-Z3O53WZR.js.map → chunk-QWUJWBZ5.js.map} +0 -0
  342. /package/dist/{chunk-RZXFXKWY.js.map → chunk-QX3K3INR.js.map} +0 -0
  343. /package/dist/{chunk-4LNCLZNK.js.map → chunk-S2GR3T7W.js.map} +0 -0
  344. /package/dist/{chunk-VPOAMPDD.js.map → chunk-SFDBLCZV.js.map} +0 -0
  345. /package/dist/{chunk-2IWBHZ3H.js.map → chunk-SIGDETMB.js.map} +0 -0
  346. /package/dist/{chunk-DBWNTLLI.js.map → chunk-STQC2FYQ.js.map} +0 -0
  347. /package/dist/{chunk-S5R77WHV.js.map → chunk-SWXPR5SE.js.map} +0 -0
  348. /package/dist/{chunk-3DNTFZAT.js.map → chunk-T32YYUT2.js.map} +0 -0
  349. /package/dist/{chunk-W5JQSVPZ.js.map → chunk-T6RQNV7E.js.map} +0 -0
  350. /package/dist/{chunk-O23QMYN4.js.map → chunk-TRN56SPQ.js.map} +0 -0
  351. /package/dist/{chunk-NM3BT2OH.js.map → chunk-TXTRHF3B.js.map} +0 -0
  352. /package/dist/{chunk-7AUIGOH4.js.map → chunk-VDVHIRCK.js.map} +0 -0
  353. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  354. /package/dist/{chunk-ZGYLPCWN.js.map → chunk-VO2BNAA2.js.map} +0 -0
  355. /package/dist/{chunk-WVEECBCG.js.map → chunk-VV2MVHCJ.js.map} +0 -0
  356. /package/dist/{chunk-B3O3IRZN.js.map → chunk-VZBW6CDG.js.map} +0 -0
  357. /package/dist/{chunk-JPKK466T.js.map → chunk-W5XWHTDO.js.map} +0 -0
  358. /package/dist/{chunk-CYG3K2T2.js.map → chunk-WR66CTVU.js.map} +0 -0
  359. /package/dist/{chunk-RP7RSENW.js.map → chunk-XQWKB6PY.js.map} +0 -0
  360. /package/dist/{chunk-64S6X4IU.js.map → chunk-XTN54NML.js.map} +0 -0
  361. /package/dist/{chunk-KYLYXGKD.js.map → chunk-YI6XIFQV.js.map} +0 -0
  362. /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
  363. /package/dist/{chunk-Y7427SL7.js.map → chunk-Z6EZCN6Z.js.map} +0 -0
  364. /package/dist/{chunk-5K2ALMSZ.js.map → chunk-ZRUC7FD3.js.map} +0 -0
  365. /package/dist/{graph-edge-decay-MKIRZ762.js.map → entity-mention-carry.js.map} +0 -0
  366. /package/dist/{resolution-BROE3TRO.js.map → entity-mention-epoch.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/offline-sync.ts"],"sourcesContent":["import { createHash, randomUUID } from \"node:crypto\";\nimport {\n lstat,\n mkdir,\n open,\n readdir,\n readFile,\n rename,\n rm,\n stat,\n unlink,\n utimes,\n writeFile,\n} from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n DEFAULT_TRANSFER_EXCLUDE_DIRS,\n} from \"./transfer/exclusions.js\";\nimport {\n prepareSafeArchiveRoot,\n resolveSafeArchiveTarget,\n sha256Bytes,\n validateArchiveRelativePath,\n type SafeArchiveRoot,\n} from \"./transfer/fs-utils.js\";\nimport { parseFlexibleIsoTimestamp } from \"./utils/iso-timestamp.js\";\nimport { EmbeddingIndexStorageError } from \"./embedding-index-storage.js\";\nimport { matchesOfflineSyncDefaultExclude } from \"./offline-sync-exclude-globs.js\";\nimport {\n applyIncomingEmbeddingGenerations,\n assertEmbeddingGenerationStillIncluded,\n computeOmittedEmbeddingGenerationPaths,\n divergedEmbeddingGenerationDeferrals,\n embeddingGenerationMembership,\n isEmbeddingGenerationDirPath,\n isPathInOmittedEmbeddingGeneration,\n} from \"./offline-sync-embedding-generation.js\";\nimport {\n applyChangesetEmbeddingGenerations,\n normalizeChangesetGenerations,\n type OfflineSyncChangesetGeneration,\n} from \"./offline-sync-changeset-generations.js\";\nimport { withEmbeddingGenerationLock, withEmbeddingGenerationLockIter } from \"./embedding-generation-lock.js\";\nimport {\n isCanonicalRuntimeStatePath,\n shouldDeleteAbsentIncomingOfflineRuntimeFile,\n shouldPreferIncomingOfflineRuntimeFile,\n} from \"./offline-sync-runtime-state.js\";\nexport { shouldPreferIncomingOfflineRuntimeFile } from \"./offline-sync-runtime-state.js\";\nexport { computeOmittedEmbeddingGenerationPaths } from \"./offline-sync-embedding-generation.js\";\nexport type { OfflineSyncChangesetGeneration } from \"./offline-sync-changeset-generations.js\";\nexport {\n compileOfflineSyncExcludeGlobs,\n globToRegExp,\n parseOfflineSyncExcludes,\n} from \"./offline-sync-exclude-globs.js\";\nimport {\n isEncryptedOfflineSyncFile,\n readPlainOfflineSyncFileChunk,\n sha256OfflineSyncFile,\n shouldExcludeOfflineSyncFile,\n type OfflineSyncExcludeFile,\n type OfflineSyncFileTarget,\n plainFileDigest,\n SYNC_INTERNAL_DIR,\n setSafeFileMtime,\n assertNonNegativeFinite,\n assertOfflineSyncMtimeMs,\n OFFLINE_SYNC_FAST_BASE_MTIME_TOLERANCE_MS,\n} from \"./offline-sync-file-io.js\";\nimport { CENSUS_MAX_MTIME_MS, isSha256Hex } from \"./census-validation.js\";\nimport {\n cleanupOfflineUpload,\n digestOfflineUploadStagingContent,\n pruneOfflineUploadStaging,\n writeOfflineUploadChunk,\n writeSafeFileFromUpload,\n hashText,\n type OfflineUploadStaging,\n} from \"./offline-sync-upload-staging.js\";\nexport type { OfflineSyncExcludeFile, OfflineSyncFileTarget } from \"./offline-sync-file-io.js\";\n\nexport const OFFLINE_SYNC_SNAPSHOT_FORMAT = \"remnic.offline-sync.snapshot.v1\";\nexport const OFFLINE_SYNC_CHANGESET_FORMAT = \"remnic.offline-sync.changeset.v1\";\nexport const OFFLINE_SYNC_STATE_VERSION = 1;\nexport const OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES = 64 * 1024 * 1024;\nexport const OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES = 8 * 1024 * 1024;\nexport const OFFLINE_SYNC_APPLY_MAX_BODY_BYTES = 16 * 1024 * 1024;\nexport const OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES = 64 * 1024 * 1024;\nexport const OFFLINE_SYNC_MAX_MTIME_MS = CENSUS_MAX_MTIME_MS;\n\nexport interface OfflineSyncFileState {\n path: string;\n sha256: string;\n /** Byte length of the transferable content, after any readFile hook such as secure-store decryption. */\n bytes: number;\n mtimeMs: number;\n}\n\nexport interface OfflineSyncFileRecord extends OfflineSyncFileState {\n contentBase64?: string;\n}\n\nexport interface OfflineSyncFileDigest {\n sha256: string;\n bytes: number;\n}\n\nexport interface OfflineSyncDeletionRevision {\n path: string;\n mtimeMs: number;\n}\n\nexport interface OfflineSyncSnapshot {\n format: typeof OFFLINE_SYNC_SNAPSHOT_FORMAT;\n schemaVersion: 1;\n createdAt: string;\n sourceId: string;\n includeTranscripts: boolean;\n files: OfflineSyncFileRecord[];\n deletions?: OfflineSyncDeletionRevision[];\n /**\n * Embedding generation dirs whose on-disk members were ALL omitted from\n * `files` because a push filter excluded at least one member (PR #3148\n * round 4). Their absence here is NOT a delete instruction: a receiver\n * keeps its local copy and its base entries until the generation is\n * pushed unfiltered or genuinely deleted with deletion metadata.\n */\n omittedEmbeddingGenerationDirs?: string[];\n}\n\nexport type OfflineSyncChange =\n | {\n type: \"upsert\";\n path: string;\n baseSha256?: string;\n file: OfflineSyncFileRecord & { contentBase64: string };\n }\n | {\n type: \"delete\";\n path: string;\n baseSha256: string;\n mtimeMs?: number;\n };\n\nexport interface OfflineSyncChangeset {\n format: typeof OFFLINE_SYNC_CHANGESET_FORMAT;\n schemaVersion: 1;\n createdAt: string;\n sourceId: string;\n includeTranscripts: boolean;\n changes: OfflineSyncChange[];\n /**\n * Complete post-change membership of every embedding generation the\n * changeset touches (issue #3150). Absent on legacy senders: receivers\n * defer manifest-less shard upserts as conflicts instead of publishing a\n * mixed generation.\n */\n embeddingGenerations?: OfflineSyncChangesetGeneration[];\n}\n\nexport interface OfflineSyncState {\n version: typeof OFFLINE_SYNC_STATE_VERSION;\n remoteId: string;\n namespace?: string;\n includeTranscripts: boolean;\n lastSyncedAt: string;\n baseFiles: OfflineSyncFileState[];\n}\n\nexport interface OfflineSyncConflict {\n path: string;\n reason:\n | \"both_modified\"\n | \"local_deleted_remote_modified\"\n | \"local_modified_remote_deleted\"\n | \"remote_exists_for_local_create\"\n | \"remote_changed_for_local_update\"\n | \"remote_deleted_for_local_update\"\n | \"remote_changed_for_local_delete\"\n // Changeset generation deferrals (#3150): the receiver refused a whole\n // embedding generation; surfaced as conflicts so the push side never\n // checkpoints it as applied.\n | \"embedding_generation_diverged\"\n | \"embedding_generation_manifest_required\";\n baseSha256?: string;\n localSha256?: string;\n incomingSha256?: string;\n conflictPath?: string;\n}\n\nexport interface OfflineSyncApplySnapshotResult {\n upserted: number;\n deleted: number;\n skipped: number;\n pendingLocal: number;\n conflicts: OfflineSyncConflict[];\n nextBaseFiles: OfflineSyncFileState[];\n}\n\nexport interface OfflineSyncApplyChangesetResult {\n appliedUpserts: number;\n appliedDeletes: number;\n skipped: number;\n conflicts: OfflineSyncConflict[];\n currentFiles: OfflineSyncFileState[];\n currentFilesComplete?: boolean;\n}\n\nexport interface OfflineSyncChangesetSummary {\n upserts: number;\n deletes: number;\n total: number;\n}\n\nexport interface OfflineSyncFileDeleteTarget extends OfflineSyncFileTarget {\n mtimeMs?: number;\n}\n\nexport type OfflineSyncRecordDeletionRevision = (\n target: OfflineSyncFileDeleteTarget & { mtimeMs: number },\n) => Promise<void>;\n\nexport interface OfflineSyncFileWriteTarget extends OfflineSyncFileTarget {\n content: Buffer;\n}\n\nexport interface OfflineSyncFileWriteChunksTarget extends OfflineSyncFileTarget {\n chunks: AsyncIterable<Buffer>;\n}\n\nexport interface OfflineSyncFileStagingWriteTarget extends OfflineSyncFileWriteTarget {\n /**\n * ABSOLUTE final path whose canonical AAD the staged ciphertext binds\n * (secure-store deployments): the offline-sync embedding generation\n * transaction stages under a staging dir and publishes by rename, so the\n * ciphertext must decrypt at the FINAL path. The AAD derives through the\n * same filePathAad logic as ordinary reads (platform-consistent).\n */\n finalAadFilePath?: string;\n}\n\nexport interface OfflineSyncFileStagingReadTarget extends OfflineSyncFileTarget {\n /** See {@link OfflineSyncFileStagingWriteTarget.finalAadFilePath}. */\n finalAadFilePath?: string;\n}\n\nexport interface OfflineSyncFileContentChunk extends Omit<OfflineSyncFileState, \"sha256\"> {\n sha256?: string;\n offset: number;\n chunkBytes: number;\n content: Buffer;\n}\n\nexport interface OfflineSyncApplyFileContentChunkResult {\n path: string;\n sha256: string;\n bytes: number;\n mtimeMs: number;\n offset: number;\n chunkBytes: number;\n done: boolean;\n applied: boolean;\n skipped: boolean;\n conflict?: OfflineSyncConflict;\n currentFile?: OfflineSyncFileState;\n}\n\ninterface OfflineSyncFileRecordOptions {\n root: SafeArchiveRoot;\n relPath: string;\n filePath: string;\n includeContent: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n signal?: AbortSignal;\n}\n\nconst OFFLINE_SYNC_FAST_BASE_CTIME_TOLERANCE_MS = 1;\nconst EXCLUDED_FILE_NAMES = new Set([\n \".sync-state.json\",\n]);\n\nconst EXCLUDED_FILE_PREFIXES = [\n \".remnic-sync.\",\n \".remnic-sync-state.\",\n];\n\n/**\n * Convert a tiny subset of glob syntax (`*`, `**`, `?`, literal text) into a\n * regular expression anchored at the start and end of the input. The matcher\n * is intentionally narrow — it is only used for operator-supplied\n * `offlineSyncExcludes` entries, not for full shell-style globbing.\n * `*` and `?` match within a single path segment. `**` is cross-segment\n * wherever it appears: a `star-star-slash` prefix (leading or embedded)\n * matches zero or more whole segments, and a trailing `dir/star-star`\n * matches everything under `dir/` at any depth.\n */\n\n\nfunction sha256Buffer(buffer: Buffer): { sha256: string; bytes: number } {\n return sha256Bytes(buffer);\n}\n\nfunction throwIfOfflineSyncAborted(signal: AbortSignal | undefined): void {\n if (!signal?.aborted) return;\n throw new Error(\"offline sync request aborted\");\n}\n\nfunction compareByPath<T extends { path: string }>(left: T, right: T): number {\n return left.path.localeCompare(right.path);\n}\n\nfunction assertSha256(value: unknown, field: string): string {\n if (!isSha256Hex(value)) {\n throw new Error(`${field} must be a 64-character sha256 hex string`);\n }\n return value.toLowerCase();\n}\n\nfunction assertNonNegativeInteger(value: unknown, field: string): number {\n if (\n typeof value !== \"number\" ||\n !Number.isFinite(value) ||\n !Number.isInteger(value) ||\n value < 0\n ) {\n throw new Error(`${field} must be a non-negative integer`);\n }\n return value;\n}\n\n\n\nfunction assertBoolean(value: unknown, field: string): boolean {\n if (typeof value !== \"boolean\") {\n throw new Error(`${field} must be a boolean`);\n }\n return value;\n}\n\nfunction normalizeSourceId(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0 || value.length > 512) {\n throw new Error(`${field} must be a non-empty string no longer than 512 characters`);\n }\n return value.trim();\n}\n\nfunction normalizeFileState(input: unknown, fieldPrefix: string): OfflineSyncFileState {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(`${fieldPrefix} must be an object`);\n }\n const obj = input as Record<string, unknown>;\n const relPath = normalizeRelativePath(obj.path, `${fieldPrefix}.path`);\n return {\n path: relPath,\n sha256: assertSha256(obj.sha256, `${fieldPrefix}.sha256`),\n bytes: assertNonNegativeInteger(obj.bytes, `${fieldPrefix}.bytes`),\n mtimeMs: assertOfflineSyncMtimeMs(obj.mtimeMs, `${fieldPrefix}.mtimeMs`),\n };\n}\n\nfunction normalizeFileRecord(\n input: unknown,\n fieldPrefix: string,\n requireContent: boolean,\n): OfflineSyncFileRecord {\n const state = normalizeFileState(input, fieldPrefix);\n const obj = input as Record<string, unknown>;\n const contentBase64 = obj.contentBase64;\n if (requireContent && typeof contentBase64 !== \"string\") {\n throw new Error(`${fieldPrefix}.contentBase64 is required`);\n }\n if (contentBase64 !== undefined && typeof contentBase64 !== \"string\") {\n throw new Error(`${fieldPrefix}.contentBase64 must be a base64 string`);\n }\n return {\n ...state,\n ...(contentBase64 !== undefined ? { contentBase64 } : {}),\n };\n}\n\nfunction normalizeFileStates(input: readonly unknown[] | undefined): OfflineSyncFileState[] {\n if (!input) return [];\n if (!Array.isArray(input)) {\n throw new Error(\"baseFiles must be an array\");\n }\n return input.map((entry, index) => normalizeFileState(entry, `baseFiles[${index}]`));\n}\n\nfunction normalizeDeletionRevisions(\n input: unknown,\n fieldPrefix: string,\n): OfflineSyncDeletionRevision[] | undefined {\n if (input === undefined) return undefined;\n if (!Array.isArray(input)) {\n throw new Error(`${fieldPrefix} must be an array`);\n }\n const deletions = input.map((entry, index): OfflineSyncDeletionRevision => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`${fieldPrefix}[${index}] must be an object`);\n }\n const obj = entry as Record<string, unknown>;\n return {\n path: normalizeRelativePath(obj.path, `${fieldPrefix}[${index}].path`),\n mtimeMs: assertOfflineSyncMtimeMs(obj.mtimeMs, `${fieldPrefix}[${index}].mtimeMs`),\n };\n });\n assertUniquePaths(deletions, fieldPrefix);\n return deletions.sort(compareByPath);\n}\n\nfunction snapshotBuilderDeletions(options: {\n deletions?: readonly OfflineSyncDeletionRevision[];\n files: readonly OfflineSyncFileState[];\n paths?: readonly string[];\n includeTranscripts: boolean;\n excludeNodeLocalState?: boolean;\n userExcludeRegexps?: readonly RegExp[];\n /** Generation dirs omitted by the push enumeration (PR #3148): revisions\n * for ANY member — including already-absent ones — are suppressed, so a\n * filtered generation can never be announced as deleted. */\n omittedGenerationDirs?: ReadonlySet<string>;\n}): OfflineSyncDeletionRevision[] | undefined {\n const deletions = normalizeDeletionRevisions(options.deletions, \"deletions\");\n if (deletions === undefined) return undefined;\n if (deletions.length === 0) return deletions;\n const presentPaths = new Set(options.files.map((file) => file.path.toLowerCase()));\n const scopedPaths = options.paths\n ? new Set(options.paths.map((relPath) => relPath.toLowerCase()))\n : undefined;\n return deletions.filter((deletion) =>\n (scopedPaths === undefined || scopedPaths.has(deletion.path.toLowerCase())) &&\n !presentPaths.has(deletion.path.toLowerCase()) &&\n !isDeletionInOmittedGeneration(deletion.path, options.omittedGenerationDirs) &&\n !(options.excludeNodeLocalState === false\n ? shouldExcludeRelPath(deletion.path, options.includeTranscripts)\n : shouldExcludePushRelPath(\n deletion.path,\n options.includeTranscripts,\n options.userExcludeRegexps,\n )));\n}\n\nfunction isDeletionInOmittedGeneration(\n relPath: string,\n omittedGenerationDirs: ReadonlySet<string> | undefined,\n): boolean {\n if (!omittedGenerationDirs || omittedGenerationDirs.size === 0) return false;\n const membership = embeddingGenerationMembership(relPath);\n return membership !== null && omittedGenerationDirs.has(membership.shardDir);\n}\n\nexport async function filterOfflineSyncDeletionRevisions(options: {\n root: string;\n deletions: readonly OfflineSyncDeletionRevision[];\n includeTranscripts?: boolean;\n userExcludeRegexps?: readonly RegExp[];\n excludeFile?: OfflineSyncExcludeFile;\n}): Promise<OfflineSyncDeletionRevision[]> {\n const deletions = normalizeDeletionRevisions(options.deletions, \"deletions\");\n if (deletions === undefined) throw new Error(\"deletions must be an array\");\n if (deletions.length === 0) return deletions;\n const root = await prepareSafeArchiveRoot(\n path.resolve(options.root),\n \"filterOfflineSyncDeletionRevisions\",\n \"root\",\n );\n const includeTranscripts = options.includeTranscripts !== false;\n const omission = await computeOmittedEmbeddingGenerationPaths({\n rootAbs: root.abs,\n userExcludeRegexps: options.userExcludeRegexps,\n excludeFile: options.excludeFile,\n isExcludedRelPath: (relPath) =>\n shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps),\n });\n const omittedDirs = new Set(omission.omittedDirs);\n const filtered: OfflineSyncDeletionRevision[] = [];\n for (const deletion of deletions) {\n if (\n shouldExcludePushRelPath(deletion.path, includeTranscripts, options.userExcludeRegexps) ||\n isDeletionInOmittedGeneration(deletion.path, omittedDirs)\n ) {\n continue;\n }\n const filePath = path.join(root.abs, ...deletion.path.split(\"/\"));\n const present = await lstat(filePath).then(\n () => true,\n (error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw error;\n },\n );\n if (!present) filtered.push(deletion);\n }\n return filtered;\n}\n\nexport function normalizeOfflineSyncSnapshot(\n input: unknown,\n options: { requireContent?: boolean } = {},\n): OfflineSyncSnapshot {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"offline sync snapshot must be an object\");\n }\n const obj = input as Record<string, unknown>;\n if (obj.format !== OFFLINE_SYNC_SNAPSHOT_FORMAT) {\n throw new Error(`offline sync snapshot format must be ${OFFLINE_SYNC_SNAPSHOT_FORMAT}`);\n }\n if (obj.schemaVersion !== 1) {\n throw new Error(\"offline sync snapshot schemaVersion must be 1\");\n }\n const createdAt = normalizeIsoString(obj.createdAt, \"createdAt\");\n const sourceId = normalizeSourceId(obj.sourceId, \"sourceId\");\n const includeTranscripts = assertBoolean(obj.includeTranscripts, \"includeTranscripts\");\n if (!Array.isArray(obj.files)) {\n throw new Error(\"offline sync snapshot files must be an array\");\n }\n const files = obj.files\n .map((entry, index) =>\n normalizeFileRecord(entry, `files[${index}]`, options.requireContent === true))\n .filter((file) => !shouldIgnoreIncomingRuntimePath(file.path))\n .sort(compareByPath);\n const deletions = normalizeDeletionRevisions(obj.deletions, \"deletions\")\n ?.filter((deletion) => !shouldIgnoreIncomingRuntimePath(deletion.path));\n const entries = deletions && deletions.length > 0 ? [...files, ...deletions] : files;\n assertUniquePaths(entries, \"offline sync snapshot\");\n if (!includeTranscripts) {\n const transcriptPath = entries\n .find((entry) => entry.path.split(\"/\")[0] === \"transcripts\")?.path;\n if (transcriptPath) {\n throw new Error(\n `offline sync snapshot includeTranscripts is false but contains transcript path: ${transcriptPath}`,\n );\n }\n }\n const excludedPath = entries\n .find((entry) => shouldExcludeRelPath(entry.path, true))?.path;\n if (excludedPath) {\n throw new Error(`offline sync snapshot contains excluded path: ${excludedPath}`);\n }\n let omittedEmbeddingGenerationDirs: string[] | undefined;\n if (obj.omittedEmbeddingGenerationDirs !== undefined) {\n if (!Array.isArray(obj.omittedEmbeddingGenerationDirs)) {\n throw new Error(\"offline sync snapshot omittedEmbeddingGenerationDirs must be an array\");\n }\n const seenDirs = new Set<string>();\n for (const [index, entry] of obj.omittedEmbeddingGenerationDirs.entries()) {\n if (\n typeof entry !== \"string\" ||\n !isEmbeddingGenerationDirPath(entry) ||\n seenDirs.has(entry)\n ) {\n throw new Error(\n `omittedEmbeddingGenerationDirs[${index}] must be a unique canonical embeddings generation dir`,\n );\n }\n seenDirs.add(entry);\n }\n omittedEmbeddingGenerationDirs = [...seenDirs].sort((left, right) => left.localeCompare(right));\n }\n return {\n format: OFFLINE_SYNC_SNAPSHOT_FORMAT,\n schemaVersion: 1,\n createdAt,\n sourceId,\n includeTranscripts,\n files,\n ...(deletions === undefined ? {} : { deletions }),\n ...(omittedEmbeddingGenerationDirs === undefined ? {} : { omittedEmbeddingGenerationDirs }),\n };\n}\n\nexport function normalizeOfflineSyncChangeset(\n input: unknown,\n): OfflineSyncChangeset {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"offline sync changeset must be an object\");\n }\n const obj = input as Record<string, unknown>;\n if (obj.format !== OFFLINE_SYNC_CHANGESET_FORMAT) {\n throw new Error(`offline sync changeset format must be ${OFFLINE_SYNC_CHANGESET_FORMAT}`);\n }\n if (obj.schemaVersion !== 1) {\n throw new Error(\"offline sync changeset schemaVersion must be 1\");\n }\n const createdAt = normalizeIsoString(obj.createdAt, \"createdAt\");\n const sourceId = normalizeSourceId(obj.sourceId, \"sourceId\");\n const includeTranscripts = assertBoolean(obj.includeTranscripts, \"includeTranscripts\");\n if (!Array.isArray(obj.changes)) {\n throw new Error(\"offline sync changeset changes must be an array\");\n }\n const changes = obj.changes.map((entry, index): OfflineSyncChange => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new Error(`changes[${index}] must be an object`);\n }\n const change = entry as Record<string, unknown>;\n const type = change.type;\n const relPath = normalizeRelativePath(change.path, `changes[${index}].path`);\n if (type === \"upsert\") {\n const file = normalizeFileRecord(\n change.file,\n `changes[${index}].file`,\n true,\n ) as OfflineSyncFileRecord & { contentBase64: string };\n if (file.path !== relPath) {\n throw new Error(`changes[${index}].file.path must match changes[${index}].path`);\n }\n const baseSha256 =\n change.baseSha256 === undefined\n ? undefined\n : assertSha256(change.baseSha256, `changes[${index}].baseSha256`);\n return {\n type: \"upsert\",\n path: relPath,\n ...(baseSha256 ? { baseSha256 } : {}),\n file,\n };\n }\n if (type === \"delete\") {\n const mtimeMs = change.mtimeMs === undefined\n ? undefined\n : assertOfflineSyncMtimeMs(change.mtimeMs, `changes[${index}].mtimeMs`);\n return {\n type: \"delete\",\n path: relPath,\n baseSha256: assertSha256(change.baseSha256, `changes[${index}].baseSha256`),\n ...(mtimeMs === undefined ? {} : { mtimeMs }),\n };\n }\n throw new Error(`changes[${index}].type must be \"upsert\" or \"delete\"`);\n }).filter((change) => !shouldIgnoreIncomingRuntimePath(change.path));\n assertUniquePaths(changes, \"offline sync changeset\");\n if (!includeTranscripts) {\n const transcriptPath = changes.find((change) => change.path.split(\"/\")[0] === \"transcripts\")?.path;\n if (transcriptPath) {\n throw new Error(\n `offline sync changeset includeTranscripts is false but contains transcript path: ${transcriptPath}`,\n );\n }\n }\n const excludedPath = changes.find((change) => shouldExcludeRelPath(change.path, true))?.path;\n if (excludedPath) {\n throw new Error(`offline sync changeset contains excluded path: ${excludedPath}`);\n }\n const embeddingGenerations = normalizeChangesetGenerations(obj.embeddingGenerations, changes);\n return {\n format: OFFLINE_SYNC_CHANGESET_FORMAT,\n schemaVersion: 1,\n createdAt,\n sourceId,\n includeTranscripts,\n changes: changes.sort(compareByPath),\n ...(embeddingGenerations === undefined ? {} : { embeddingGenerations }),\n };\n}\n\nfunction normalizeIsoString(input: unknown, field: string): string {\n if (typeof input !== \"string\" || input.trim().length === 0) {\n throw new Error(`${field} must be an ISO timestamp string`);\n }\n const parsed = parseFlexibleIsoTimestamp(input.trim());\n if (parsed === null) {\n throw new Error(`${field} must be a parseable ISO timestamp`);\n }\n return new Date(parsed).toISOString();\n}\n\nfunction normalizeRelativePath(input: unknown, field: string): string {\n if (typeof input !== \"string\") {\n throw new Error(`${field} must be a POSIX relative path string`);\n }\n return validateArchiveRelativePath(input, field);\n}\n\nfunction assertUniquePaths(entries: readonly { path: string }[], context: string): void {\n const seen = new Set<string>();\n for (const entry of entries) {\n const key = entry.path.toLowerCase();\n if (seen.has(key)) {\n throw new Error(`${context} contains duplicate path: ${entry.path}`);\n }\n seen.add(key);\n }\n}\n\nexport function isInternalRemnicStatePath(relPosix: string): boolean {\n const normalized = relPosix.includes(\"\\\\\") ? relPosix.replaceAll(\"\\\\\", \"/\") : relPosix;\n return normalized === \".remnic\"\n || normalized.startsWith(\".remnic/\")\n || normalized.endsWith(\"/.remnic\")\n || normalized.includes(\"/.remnic/\");\n}\n\nfunction shouldExcludeRelPath(relPosix: string, includeTranscripts: boolean): boolean {\n if (isInternalRemnicStatePath(relPosix)) return true;\n const parts = relPosix.split(\"/\");\n if (parts.some((part) => DEFAULT_TRANSFER_EXCLUDE_DIRS.has(part))) return true;\n if (parts.some((part) => part === SYNC_INTERNAL_DIR)) return true;\n if (!includeTranscripts && parts[0] === \"transcripts\") return true;\n const basename = parts[parts.length - 1] ?? \"\";\n if (isCanonicalRuntimeStatePath(parts) && basename.includes(\".tmp-\")) return true;\n if (EXCLUDED_FILE_NAMES.has(basename)) return true;\n if (EXCLUDED_FILE_PREFIXES.some((prefix) => basename.startsWith(prefix))) return true;\n return false;\n}\n\n/**\n * Push-side variant of `shouldExcludeRelPath` for issue #1786. Combines the\n * legacy structural exclude (private dirs, sync internal, tmp runtime state,\n * excluded file names/prefixes) with the new push-only exclusion layers:\n * - the `state/*.sqlite`, `state/index_tags.json`, etc. defaults that\n * describe node-local runtime state each node rebuilds from synced\n * records, and\n * - operator-supplied `offlineSyncExcludes` regexps.\n *\n * Used ONLY by push-side enumeration/validation paths. Apply-side callers\n * must use the legacy `shouldExcludeRelPath` so a remote snapshot containing\n * `state/lcm.sqlite` can still be accepted on first sync -- the remote's\n * view is authoritative for that file until the local LCM is bootstrapped.\n */\nfunction shouldExcludePushRelPath(\n relPosix: string,\n includeTranscripts: boolean,\n userExcludeRegexps?: readonly RegExp[],\n): boolean {\n if (shouldExcludeRelPath(relPosix, includeTranscripts)) return true;\n // Issue #1786: node-local runtime state (live sqlite, derived indexes,\n // per-node governance run logs) is rebuilt by each node, never synced.\n if (matchesOfflineSyncDefaultExclude(relPosix)) return true;\n if (userExcludeRegexps && userExcludeRegexps.some((re) => re.test(relPosix))) return true;\n return false;\n}\n\n// Precompiled once at module load — this check sits on the hot\n// enumeration path for every walked file (Kilo review, PR #1793).\n\n\n/**\n * Compile operator-supplied `offlineSyncExcludes` glob strings into a\n * pre-validated array of regular expressions. Empty input is allowed and\n * returns an empty list. Throws on any invalid entry — callers should treat\n * a thrown error as a fatal configuration mistake and refuse to start the\n * sync run rather than silently dropping the bad entry.\n */\n\nfunction shouldIgnoreIncomingRuntimePath(relPosix: string): boolean {\n if (isInternalRemnicStatePath(relPosix)) return true;\n const parts = relPosix.split(\"/\");\n const basename = parts[parts.length - 1] ?? \"\";\n return isCanonicalRuntimeStatePath(parts) && basename.includes(\".tmp-\");\n}\n\nfunction filterBaseFilesForMode(\n files: readonly OfflineSyncFileState[],\n includeTranscripts: boolean,\n): OfflineSyncFileState[] {\n return files.filter((file) => !shouldExcludeRelPath(file.path, includeTranscripts));\n}\n\nfunction canReuseFastBaseFileState(\n baseEntry: OfflineSyncFileState,\n st: { size: number; mtimeMs: number; ctimeMs: number },\n baseCapturedAtMs: number | null,\n): boolean {\n if (baseEntry.bytes !== st.size) return false;\n if (Math.abs(baseEntry.mtimeMs - st.mtimeMs) > OFFLINE_SYNC_FAST_BASE_MTIME_TOLERANCE_MS) {\n return false;\n }\n if (baseCapturedAtMs === null) return false;\n // Node reports stat times as fractional milliseconds while Date snapshots are\n // whole milliseconds, so allow only a tiny precision window around capture.\n return st.ctimeMs - baseCapturedAtMs <= OFFLINE_SYNC_FAST_BASE_CTIME_TOLERANCE_MS;\n}\n\nasync function canReuseFastBaseFileStateFromDisk(\n baseEntry: OfflineSyncFileState,\n st: { size: number; mtimeMs: number; ctimeMs: number },\n baseCapturedAtMs: number | null,\n): Promise<boolean> {\n return canReuseFastBaseFileState(baseEntry, st, baseCapturedAtMs);\n}\n\nasync function readOfflineSyncFileRecord(\n options: OfflineSyncFileRecordOptions,\n): Promise<OfflineSyncFileRecord> {\n throwIfOfflineSyncAborted(options.signal);\n const relPath = validateArchiveRelativePath(options.relPath, \"offlineSyncFile.path\");\n let content: Buffer | null = null;\n let digest: OfflineSyncFileDigest;\n if (options.includeContent) {\n content = options.readFile\n ? await options.readFile({ root: options.root.abs, path: relPath, filePath: options.filePath })\n : await readFile(options.filePath);\n throwIfOfflineSyncAborted(options.signal);\n digest = sha256Buffer(content);\n } else if (options.readFileDigest) {\n digest = await options.readFileDigest({ root: options.root.abs, path: relPath, filePath: options.filePath });\n throwIfOfflineSyncAborted(options.signal);\n } else if (options.readFile) {\n content = await options.readFile({ root: options.root.abs, path: relPath, filePath: options.filePath });\n throwIfOfflineSyncAborted(options.signal);\n digest = sha256Buffer(content);\n content = null;\n } else {\n digest = await sha256OfflineSyncFile(options.filePath, options.signal);\n }\n throwIfOfflineSyncAborted(options.signal);\n const st = await stat(options.filePath);\n return {\n path: relPath,\n sha256: digest.sha256,\n bytes: digest.bytes,\n mtimeMs: st.mtimeMs,\n ...(content ? { contentBase64: content.toString(\"base64\") } : {}),\n };\n}\n\nexport async function* iterateOfflineSyncSnapshotFileRecords(options: {\n root: string;\n includeContent?: boolean;\n includeTranscripts?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n excludeFile?: OfflineSyncExcludeFile;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * Precomputed whole-generation omission set (PR #3148 round 4): paths the\n * walk must skip because their embedding generation lost ANY member to a\n * push filter. When omitted and push excludes are active, the set is\n * computed here so streaming census consumers get the same semantics.\n */\n skipEmbeddingGenerationPaths?: ReadonlySet<string>;\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n signal?: AbortSignal;\n}): AsyncIterable<OfflineSyncFileRecord> {\n throwIfOfflineSyncAborted(options.signal);\n const rootAbs = path.resolve(options.root);\n const root = await prepareSafeArchiveRoot(rootAbs, \"iterateOfflineSyncSnapshotFileRecords\", \"root\");\n const includeTranscripts = options.includeTranscripts !== false;\n const pushExcludes = options.excludeNodeLocalState !== false;\n const skipGenerationPaths = options.skipEmbeddingGenerationPaths ??\n (pushExcludes\n ? (await computeOmittedEmbeddingGenerationPaths({\n rootAbs: root.abs,\n userExcludeRegexps: options.userExcludeRegexps,\n excludeFile: options.excludeFile,\n isExcludedRelPath: (relPath) =>\n shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps),\n })).omittedPaths\n : undefined);\n\n async function* walk(dirAbs: string, includeContent = options.includeContent === true): AsyncIterable<OfflineSyncFileRecord> {\n throwIfOfflineSyncAborted(options.signal);\n let entries = await readdir(dirAbs, { withFileTypes: true });\n entries = entries.sort((left, right) => left.name.localeCompare(right.name));\n for (const entry of entries) {\n const abs = path.join(dirAbs, entry.name);\n const relPosix = path.relative(root.abs, abs).split(path.sep).join(\"/\");\n if (\n options.excludeNodeLocalState === false\n ? shouldExcludeRelPath(relPosix, includeTranscripts)\n : shouldExcludePushRelPath(relPosix, includeTranscripts, options.userExcludeRegexps)\n ) continue;\n if (skipGenerationPaths?.has(relPosix)) continue;\n if (entry.isSymbolicLink()) continue;\n if (entry.isDirectory()) {\n if (isEmbeddingGenerationDirPath(relPosix)) {\n yield* withEmbeddingGenerationLockIter(path.dirname(abs), (content) => walk(abs, content), includeContent,\n () => assertEmbeddingGenerationStillIncluded(root.abs, relPosix, options.excludeFile,\n (rel) => shouldExcludePushRelPath(rel, includeTranscripts, options.userExcludeRegexps),\n []));\n continue;\n }\n yield* walk(abs, includeContent);\n continue;\n }\n if (!entry.isFile()) continue;\n if (await shouldExcludeOfflineSyncFile(options.excludeFile, {\n root: root.abs,\n path: relPosix,\n filePath: abs,\n })) continue;\n yield await readOfflineSyncFileRecord({\n root,\n relPath: relPosix,\n filePath: abs,\n includeContent,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n signal: options.signal,\n });\n }\n }\n\n yield* walk(root.abs);\n}\n\nexport async function buildOfflineSyncSnapshot(options: {\n root: string;\n sourceId: string;\n includeContent?: boolean;\n deletions?: readonly OfflineSyncDeletionRevision[];\n includeTranscripts?: boolean;\n now?: Date;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n excludeFile?: OfflineSyncExcludeFile;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n signal?: AbortSignal;\n}): Promise<OfflineSyncSnapshot> {\n throwIfOfflineSyncAborted(options.signal);\n const includeTranscripts = options.includeTranscripts !== false;\n const pushExcludes = options.excludeNodeLocalState !== false;\n const normalizedDeletions = normalizeDeletionRevisions(options.deletions, \"deletions\");\n const omission = pushExcludes\n ? await computeOmittedEmbeddingGenerationPaths({\n rootAbs: path.resolve(options.root),\n userExcludeRegexps: options.userExcludeRegexps,\n excludeFile: options.excludeFile,\n tombstonedPaths: (normalizedDeletions ?? []).map((deletion) => deletion.path),\n isExcludedRelPath: (relPath) =>\n shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps),\n })\n : undefined;\n const files: OfflineSyncFileRecord[] = [];\n for await (const file of iterateOfflineSyncSnapshotFileRecords({\n ...options,\n skipEmbeddingGenerationPaths: omission?.omittedPaths,\n })) files.push(file);\n throwIfOfflineSyncAborted(options.signal);\n\n const sortedFiles = files.sort(compareByPath);\n const deletions = snapshotBuilderDeletions({\n deletions: options.deletions,\n files: sortedFiles,\n includeTranscripts,\n excludeNodeLocalState: options.excludeNodeLocalState,\n userExcludeRegexps: options.userExcludeRegexps,\n omittedGenerationDirs: omission && omission.omittedDirs.length > 0\n ? new Set(omission.omittedDirs)\n : undefined,\n });\n return {\n format: OFFLINE_SYNC_SNAPSHOT_FORMAT,\n schemaVersion: 1,\n createdAt: (options.now ?? new Date()).toISOString(),\n sourceId: normalizeSourceId(options.sourceId, \"sourceId\"),\n includeTranscripts,\n files: sortedFiles,\n ...(deletions === undefined ? {} : { deletions }),\n ...(omission && omission.omittedDirs.length > 0\n ? { omittedEmbeddingGenerationDirs: omission.omittedDirs }\n : {}),\n };\n}\n\nexport async function buildOfflineSyncSnapshotFromBase(options: {\n root: string;\n sourceId: string;\n baseFiles?: readonly OfflineSyncFileState[];\n deletions?: readonly OfflineSyncDeletionRevision[];\n baseCapturedAt?: Date;\n includeContent?: boolean;\n includeTranscripts?: boolean;\n now?: Date;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n excludeFile?: OfflineSyncExcludeFile;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n signal?: AbortSignal;\n}): Promise<OfflineSyncSnapshot> {\n throwIfOfflineSyncAborted(options.signal);\n const rootAbs = path.resolve(options.root);\n const root = await prepareSafeArchiveRoot(rootAbs, \"buildOfflineSyncSnapshotFromBase\", \"root\");\n const includeTranscripts = options.includeTranscripts !== false;\n const base = byPath(filterBaseFilesForMode(\n normalizeFileStates(options.baseFiles),\n includeTranscripts,\n ));\n const rawBaseCapturedAtMs = options.baseCapturedAt?.getTime();\n const baseCapturedAtMs = rawBaseCapturedAtMs !== undefined && Number.isFinite(rawBaseCapturedAtMs)\n ? rawBaseCapturedAtMs\n : null;\n const pushExcludes = options.excludeNodeLocalState !== false;\n const normalizedDeletions = normalizeDeletionRevisions(options.deletions, \"deletions\");\n const omission = pushExcludes\n ? await computeOmittedEmbeddingGenerationPaths({\n rootAbs: root.abs,\n userExcludeRegexps: options.userExcludeRegexps,\n excludeFile: options.excludeFile,\n tombstonedPaths: (normalizedDeletions ?? []).map((deletion) => deletion.path),\n isExcludedRelPath: (relPath) =>\n shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps),\n })\n : undefined;\n const files: OfflineSyncFileRecord[] = [];\n\n async function walk(dirAbs: string): Promise<void> {\n throwIfOfflineSyncAborted(options.signal);\n let entries = await readdir(dirAbs, { withFileTypes: true });\n entries = entries.sort((left, right) => left.name.localeCompare(right.name));\n for (const entry of entries) {\n throwIfOfflineSyncAborted(options.signal);\n const abs = path.join(dirAbs, entry.name);\n const relPosix = path.relative(root.abs, abs).split(path.sep).join(\"/\");\n if (\n options.excludeNodeLocalState === false\n ? shouldExcludeRelPath(relPosix, includeTranscripts)\n : shouldExcludePushRelPath(relPosix, includeTranscripts, options.userExcludeRegexps)\n ) continue;\n if (omission?.omittedPaths.has(relPosix)) continue;\n if (entry.isSymbolicLink()) continue;\n if (entry.isDirectory()) {\n if (isEmbeddingGenerationDirPath(relPosix)) {\n await withEmbeddingGenerationLock(path.dirname(abs), async () => {\n await assertEmbeddingGenerationStillIncluded(root.abs, relPosix, options.excludeFile,\n (rel) => shouldExcludePushRelPath(rel, includeTranscripts, options.userExcludeRegexps),\n (normalizedDeletions ?? []).map((deletion) => deletion.path));\n await walk(abs);\n });\n continue;\n }\n await walk(abs);\n continue;\n }\n if (!entry.isFile()) continue;\n if (await shouldExcludeOfflineSyncFile(options.excludeFile, {\n root: root.abs,\n path: relPosix,\n filePath: abs,\n })) continue;\n const st = await stat(abs);\n const baseEntry = base.get(relPosix);\n if (\n options.includeContent !== true &&\n baseEntry &&\n baseCapturedAtMs !== null &&\n await canReuseFastBaseFileStateFromDisk(baseEntry, st, baseCapturedAtMs)\n ) {\n files.push(baseEntry);\n continue;\n }\n files.push(await readOfflineSyncFileRecord({\n root,\n relPath: relPosix,\n filePath: abs,\n includeContent: options.includeContent === true,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n signal: options.signal,\n }));\n }\n }\n\n await walk(root.abs);\n throwIfOfflineSyncAborted(options.signal);\n\n const sortedFiles = files.sort(compareByPath);\n const deletions = snapshotBuilderDeletions({\n deletions: options.deletions,\n files: sortedFiles,\n includeTranscripts,\n excludeNodeLocalState: options.excludeNodeLocalState,\n userExcludeRegexps: options.userExcludeRegexps,\n omittedGenerationDirs: omission && omission.omittedDirs.length > 0\n ? new Set(omission.omittedDirs)\n : undefined,\n });\n return {\n format: OFFLINE_SYNC_SNAPSHOT_FORMAT,\n schemaVersion: 1,\n createdAt: (options.now ?? new Date()).toISOString(),\n sourceId: normalizeSourceId(options.sourceId, \"sourceId\"),\n includeTranscripts,\n files: sortedFiles,\n ...(deletions === undefined ? {} : { deletions }),\n ...(omission && omission.omittedDirs.length > 0\n ? { omittedEmbeddingGenerationDirs: omission.omittedDirs }\n : {}),\n };\n}\n\nexport async function buildOfflineSyncSnapshotForPaths(options: {\n root: string;\n sourceId: string;\n paths: readonly string[];\n deletions?: readonly OfflineSyncDeletionRevision[];\n includeContent?: boolean;\n includeTranscripts?: boolean;\n now?: Date;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n excludeFile?: OfflineSyncExcludeFile;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n signal?: AbortSignal;\n}): Promise<OfflineSyncSnapshot> {\n throwIfOfflineSyncAborted(options.signal);\n const rootAbs = path.resolve(options.root);\n const root = await prepareSafeArchiveRoot(rootAbs, \"buildOfflineSyncSnapshotForPaths\", \"root\");\n const includeTranscripts = options.includeTranscripts !== false;\n const files: OfflineSyncFileRecord[] = [];\n const seen = new Set<string>();\n\n for (const rawPath of options.paths) {\n throwIfOfflineSyncAborted(options.signal);\n const relPath = normalizeRelativePath(rawPath, \"paths[]\");\n if (seen.has(relPath)) continue;\n seen.add(relPath);\n if (\n options.excludeNodeLocalState === false\n ? shouldExcludeRelPath(relPath, includeTranscripts)\n : shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps)\n ) {\n throw new Error(`offline sync snapshot path is excluded: ${relPath}`);\n }\n const filePath = await resolveSafeArchiveTarget(root, relPath);\n const st = await lstat(filePath).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n });\n if (!st || st.isSymbolicLink() || !st.isFile()) continue;\n if (await shouldExcludeOfflineSyncFile(options.excludeFile, {\n root: root.abs,\n path: relPath,\n filePath,\n })) {\n throw new Error(`offline sync snapshot path is excluded: ${relPath}`);\n }\n files.push(await readOfflineSyncFileRecord({\n root,\n relPath,\n filePath,\n includeContent: options.includeContent === true,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n signal: options.signal,\n }));\n }\n throwIfOfflineSyncAborted(options.signal);\n\n const sortedFiles = files.sort(compareByPath);\n const deletions = snapshotBuilderDeletions({\n deletions: options.deletions,\n files: sortedFiles,\n paths: [...seen],\n includeTranscripts,\n excludeNodeLocalState: options.excludeNodeLocalState,\n userExcludeRegexps: options.userExcludeRegexps,\n });\n return {\n format: OFFLINE_SYNC_SNAPSHOT_FORMAT,\n schemaVersion: 1,\n createdAt: (options.now ?? new Date()).toISOString(),\n sourceId: normalizeSourceId(options.sourceId, \"sourceId\"),\n includeTranscripts,\n files: sortedFiles,\n ...(deletions === undefined ? {} : { deletions }),\n };\n}\n\nexport async function readOfflineSyncFileContentChunk(options: {\n root: string;\n path: string;\n offset?: number;\n length?: number;\n includeTranscripts?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n excludeFile?: OfflineSyncExcludeFile;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n}): Promise<OfflineSyncFileContentChunk> {\n const rootAbs = path.resolve(options.root);\n const root = await prepareSafeArchiveRoot(rootAbs, \"readOfflineSyncFileContentChunk\", \"root\");\n const includeTranscripts = options.includeTranscripts !== false;\n const relPath = normalizeRelativePath(options.path, \"path\");\n if (\n options.excludeNodeLocalState === false\n ? shouldExcludeRelPath(relPath, includeTranscripts)\n : shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps)\n ) {\n throw new Error(`offline sync file content path is excluded: ${relPath}`);\n }\n const offset = options.offset === undefined\n ? 0\n : assertNonNegativeInteger(options.offset, \"offset\");\n const requestedLength = options.length === undefined\n ? OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES\n : assertNonNegativeInteger(options.length, \"length\");\n if (requestedLength < 1 || requestedLength > OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES) {\n throw new Error(\n `length must be an integer from 1 to ${OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES}`,\n );\n }\n const filePath = await resolveSafeArchiveTarget(root, relPath);\n const st = await lstat(filePath).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n });\n if (!st || st.isSymbolicLink() || !st.isFile()) {\n throw new Error(`offline sync file content path not found: ${relPath}`);\n }\n if (await shouldExcludeOfflineSyncFile(options.excludeFile, {\n root: root.abs,\n path: relPath,\n filePath,\n })) {\n throw new Error(`offline sync file content path is excluded: ${relPath}`);\n }\n const encrypted = await isEncryptedOfflineSyncFile(filePath);\n if (!encrypted) {\n if (offset > st.size) {\n throw new Error(`offset must be <= file size for ${relPath}`);\n }\n // Plain files need the whole-file sha256 for the response contract\n // (x-remnic-file-sha256; peer transports reject chunks without it), but\n // must stay memory-bounded for large files: the digest is computed by a\n // streamed hash pass (never buffering the file) and cached by\n // (path, bytes, mtimeMs) so per-chunk requests after the first are O(1).\n const chunk = await readPlainOfflineSyncFileChunk({\n filePath,\n offset,\n length: requestedLength,\n bytes: st.size,\n });\n const digest = await plainFileDigest(filePath);\n return {\n path: relPath,\n sha256: digest,\n bytes: st.size,\n mtimeMs: st.mtimeMs,\n offset,\n chunkBytes: chunk.length,\n content: chunk,\n };\n }\n if (!options.readFile) {\n throw new Error(`offline sync file content requires a secure-store read hook: ${relPath}`);\n }\n const content = await options.readFile({ root: root.abs, path: relPath, filePath });\n if (offset > content.length) {\n throw new Error(`offset must be <= file size for ${relPath}`);\n }\n const digest = sha256Buffer(content);\n const end = Math.min(content.length, offset + requestedLength);\n const chunk = content.subarray(offset, end);\n return {\n path: relPath,\n sha256: digest.sha256,\n bytes: digest.bytes,\n mtimeMs: st.mtimeMs,\n offset,\n chunkBytes: chunk.length,\n content: Buffer.from(chunk),\n };\n}\n\nexport async function buildOfflineSyncChangeset(options: {\n root: string;\n sourceId: string;\n baseFiles?: readonly OfflineSyncFileState[];\n deletions?: readonly OfflineSyncDeletionRevision[];\n baseCapturedAt?: Date;\n excludePaths?: readonly string[];\n includeTranscripts?: boolean;\n now?: Date;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n}): Promise<OfflineSyncChangeset> {\n const includeTranscripts = options.includeTranscripts !== false;\n const current = await buildOfflineSyncSnapshotFromBase({\n root: options.root,\n sourceId: options.sourceId,\n baseFiles: options.baseFiles,\n deletions: options.deletions,\n baseCapturedAt: options.baseCapturedAt,\n includeContent: false,\n includeTranscripts,\n now: options.now,\n userExcludeRegexps: options.userExcludeRegexps,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n });\n return buildOfflineSyncChangesetFromSnapshot({\n root: options.root,\n sourceId: options.sourceId,\n baseFiles: options.baseFiles,\n currentFiles: current.files,\n deletions: current.deletions,\n excludePaths: options.excludePaths,\n includeTranscripts,\n now: options.now,\n userExcludeRegexps: options.userExcludeRegexps,\n readFile: options.readFile,\n });\n}\n\nexport async function buildOfflineSyncChangesetFromSnapshot(options: {\n root: string;\n sourceId: string;\n currentFiles: readonly OfflineSyncFileState[];\n baseFiles?: readonly OfflineSyncFileState[];\n deletions?: readonly OfflineSyncDeletionRevision[];\n excludePaths?: readonly string[];\n includeTranscripts?: boolean;\n now?: Date;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n}): Promise<OfflineSyncChangeset> {\n const includeTranscripts = options.includeTranscripts !== false;\n const excludedPaths = new Set(\n (options.excludePaths ?? []).map((relPath) => normalizeRelativePath(relPath, \"excludePaths[]\")),\n );\n const base = byPath(filterBaseFilesForMode(\n normalizeFileStates(options.baseFiles),\n includeTranscripts,\n ));\n const currentMap = byPath(filterBaseFilesForMode(\n normalizeFileStates(options.currentFiles),\n includeTranscripts,\n ));\n const deletions = normalizeDeletionRevisions(options.deletions, \"deletions\");\n const deletionMtimeByPath = deletions === undefined\n ? undefined\n : new Map(deletions.map((deletion) => [deletion.path, deletion.mtimeMs] as const));\n const changes: OfflineSyncChange[] = [];\n\n for (const relPath of unionPaths(base, currentMap)) {\n if (excludedPaths.has(relPath)) continue;\n // Issue #1786: node-local runtime state must never appear in a push-side\n // changeset — each node rebuilds it from synced records.\n if (shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps)) continue;\n // Runtime state is remote-authoritative in offline sync: local edits and\n // deletes are not pushed; the pull phase restores or removes these files\n // from the remote snapshot.\n if (shouldPreferIncomingOfflineRuntimeFile(relPath)) continue;\n const baseEntry = base.get(relPath);\n const currentEntry = currentMap.get(relPath);\n if (currentEntry && currentEntry.sha256 !== baseEntry?.sha256) {\n const file = await buildOfflineSyncSnapshotForPaths({\n root: options.root,\n sourceId: options.sourceId,\n paths: [relPath],\n includeContent: true,\n includeTranscripts,\n now: options.now,\n userExcludeRegexps: options.userExcludeRegexps,\n readFile: options.readFile,\n });\n const record = file.files[0];\n if (!record || typeof record.contentBase64 !== \"string\" || record.sha256 !== currentEntry.sha256) {\n throw new Error(`offline sync file changed while building changeset: ${relPath}`);\n }\n changes.push({\n type: \"upsert\",\n path: relPath,\n ...(baseEntry ? { baseSha256: baseEntry.sha256 } : {}),\n file: record as OfflineSyncFileRecord & { contentBase64: string },\n });\n continue;\n }\n if (!currentEntry && baseEntry) {\n const mtimeMs = deletionMtimeByPath?.get(relPath);\n changes.push({\n type: \"delete\",\n path: relPath,\n baseSha256: baseEntry.sha256,\n ...(mtimeMs === undefined ? {} : { mtimeMs }),\n });\n }\n }\n\n return {\n format: OFFLINE_SYNC_CHANGESET_FORMAT,\n schemaVersion: 1,\n createdAt: (options.now ?? new Date()).toISOString(),\n sourceId: normalizeSourceId(options.sourceId, \"sourceId\"),\n includeTranscripts,\n changes: changes.sort(compareByPath),\n };\n}\n\nexport function summarizeOfflineSyncChangeset(\n changeset: OfflineSyncChangeset,\n): OfflineSyncChangesetSummary {\n const upserts = changeset.changes.filter((change) => change.type === \"upsert\").length;\n const deletes = changeset.changes.filter((change) => change.type === \"delete\").length;\n return {\n upserts,\n deletes,\n total: changeset.changes.length,\n };\n}\n\nexport async function summarizeOfflineSyncPendingChanges(options: {\n root: string;\n sourceId: string;\n baseFiles?: readonly OfflineSyncFileState[];\n baseCapturedAt?: Date;\n includeTranscripts?: boolean;\n now?: Date;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n}): Promise<OfflineSyncChangesetSummary> {\n const includeTranscripts = options.includeTranscripts !== false;\n const current = await buildOfflineSyncSnapshotFromBase({\n root: options.root,\n sourceId: options.sourceId,\n baseFiles: options.baseFiles,\n baseCapturedAt: options.baseCapturedAt,\n includeContent: false,\n includeTranscripts,\n now: options.now,\n userExcludeRegexps: options.userExcludeRegexps,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n });\n return summarizeOfflineSyncPendingFiles({\n baseFiles: options.baseFiles,\n currentFiles: current.files,\n includeTranscripts,\n userExcludeRegexps: options.userExcludeRegexps,\n });\n}\n\nexport function summarizeOfflineSyncPendingFiles(options: {\n baseFiles?: readonly OfflineSyncFileState[];\n currentFiles: readonly OfflineSyncFileState[];\n includeTranscripts?: boolean;\n userExcludeRegexps?: readonly RegExp[];\n /**\n * When false, enumeration uses only the legacy structural excludes —\n * the apply/pull-side view of local files. Push-side callers keep the\n * default (true): built-in node-local state excludes + user excludes.\n * (Cursor review on PR #1793: apply-side local enumeration must see\n * files like state/lcm.sqlite or merges misclassify them.)\n */\n excludeNodeLocalState?: boolean;\n}): OfflineSyncChangesetSummary {\n const includeTranscripts = options.includeTranscripts !== false;\n const base = byPath(filterBaseFilesForMode(\n normalizeFileStates(options.baseFiles),\n includeTranscripts,\n ));\n const currentMap = byPath(filterBaseFilesForMode(\n normalizeFileStates(options.currentFiles),\n includeTranscripts,\n ));\n let upserts = 0;\n let deletes = 0;\n for (const relPath of unionPaths(base, currentMap)) {\n if (shouldPreferIncomingOfflineRuntimeFile(relPath)) continue;\n if (shouldExcludePushRelPath(relPath, includeTranscripts, options.userExcludeRegexps)) continue;\n const baseEntry = base.get(relPath);\n const currentEntry = currentMap.get(relPath);\n if (currentEntry && currentEntry.sha256 !== baseEntry?.sha256) {\n upserts += 1;\n continue;\n }\n if (!currentEntry && baseEntry) {\n deletes += 1;\n }\n }\n\n return {\n upserts,\n deletes,\n total: upserts + deletes,\n };\n}\n\nexport async function applyOfflineSyncSnapshot(options: {\n root: string;\n snapshot: unknown;\n baseFiles?: readonly OfflineSyncFileState[];\n currentFiles?: readonly OfflineSyncFileState[];\n deferredPaths?: readonly string[];\n allowMissingConflictContent?: boolean;\n /**\n * Explicit INCOMING content source for snapshot records without inline\n * `contentBase64` (oversized generation members the client fetched\n * chunk-wise into a private staging root). Consulted only for such\n * records; return null to keep the metadata-only behavior (the local\n * file must hash-match the record). Returned buffers are digest-verified\n * against the incoming record before anything is published.\n */\n readIncomingFile?: (target: { path: string; sha256: string; bytes: number }) => Promise<Buffer | null>;\n writeConflictCopies?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n writeFile?: (target: OfflineSyncFileWriteTarget) => Promise<void>;\n writeStagingFile?: (target: OfflineSyncFileStagingWriteTarget) => Promise<void>;\n readStagingFile?: (target: OfflineSyncFileStagingReadTarget) => Promise<Buffer>;\n deleteFile?: (target: OfflineSyncFileDeleteTarget) => Promise<void>;\n recordDeletionRevision?: OfflineSyncRecordDeletionRevision;\n}): Promise<OfflineSyncApplySnapshotResult> {\n const snapshot = normalizeOfflineSyncSnapshot(options.snapshot);\n const baseMap = byPath(filterBaseFilesForMode(\n normalizeFileStates(options.baseFiles),\n snapshot.includeTranscripts,\n ));\n const incomingMap = byPath(snapshot.files);\n const deletionMtimeByPath = snapshot.deletions === undefined\n ? undefined\n : new Map(snapshot.deletions.map((deletion) => [deletion.path, deletion.mtimeMs] as const));\n const incomingBuffers = await verifyRecordContents(snapshot.files, \"offline sync snapshot\", {\n requireContent: false,\n readIncomingFile: options.readIncomingFile,\n });\n const root = await ensureSyncRoot(options.root, \"applyOfflineSyncSnapshot\");\n const currentFiles = options.currentFiles\n ? filterBaseFilesForMode(normalizeFileStates(options.currentFiles), snapshot.includeTranscripts).sort(compareByPath)\n : (await buildOfflineSyncSnapshot({\n root: root.abs,\n sourceId: \"local\",\n includeContent: false,\n includeTranscripts: snapshot.includeTranscripts,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n excludeNodeLocalState: false,\n })).files;\n const currentMap = byPath(currentFiles);\n const deferredPaths = new Set([...(options.deferredPaths ?? []),\n ...divergedEmbeddingGenerationDeferrals({\n incomingFiles: snapshot.files, baseFiles: [...baseMap.values()], currentFiles,\n }),\n ]);\n const omittedGenerationDirs = new Set(snapshot.omittedEmbeddingGenerationDirs ?? []);\n if (deletionMtimeByPath && options.recordDeletionRevision) {\n for (const [relPath, mtimeMs] of deletionMtimeByPath) {\n if (\n currentMap.has(relPath) ||\n deferredPaths.has(relPath) ||\n (omittedGenerationDirs.size > 0 &&\n isPathInOmittedEmbeddingGeneration(relPath, omittedGenerationDirs)) ||\n matchesOfflineSyncDefaultExclude(relPath)\n ) {\n continue;\n }\n await options.recordDeletionRevision({\n root: root.abs,\n path: relPath,\n filePath: await resolveSafeArchiveTarget(root, relPath),\n mtimeMs,\n });\n }\n }\n const nextBase = new Map(baseMap);\n const conflicts: OfflineSyncConflict[] = [];\n let upserted = 0;\n let deleted = 0;\n let skipped = 0;\n let pendingLocal = 0;\n const conflictIncomingBuffer = (relPath: string): Buffer | undefined => {\n if (options.writeConflictCopies === false) return undefined;\n const buffer = incomingBuffers.get(relPath);\n if (buffer || options.allowMissingConflictContent === true) return buffer;\n return requiredBuffer(incomingBuffers, relPath);\n };\n\n // Embedding generations travel and replace as ONE unit (issue #3148):\n // atomic replacement, cross-layout marker conversion, whole-generation\n // removal on tombstones — all extracted to the generation module (issue\n // #3150) so the changeset path can share it without growing this file.\n const { transactionResults, deferredGenerationDirs } = await applyIncomingEmbeddingGenerations({\n root,\n incomingMap,\n incomingBuffers,\n baseMap,\n currentMap,\n deferredPaths,\n omittedGenerationDirs,\n deletionMtimeByPath,\n io: {\n readFile: options.readFile,\n writeStagingFile: options.writeStagingFile,\n readStagingFile: options.readStagingFile,\n deleteFile: options.deleteFile,\n },\n customIoPresent: Boolean(options.writeFile || options.readFile || options.readFileDigest || options.deleteFile),\n now: Date.now(),\n });\n\n const transactionHandled = new Set<string>();\n let generationUpserted = 0;\n let generationDeleted = 0;\n for (const result of transactionResults) {\n if (result.deferredLocalDivergence) {\n for (const relPath of result.handledPaths) deferredPaths.add(relPath);\n deferredGenerationDirs.add(result.shardDirRel);\n continue;\n }\n generationUpserted += result.upserted;\n generationDeleted += result.deleted;\n for (const relPath of result.handledPaths) transactionHandled.add(relPath);\n // Record converted shard paths directly; they may not be in any input map.\n for (const [relPath, state] of result.writtenStates) {\n nextBase.set(relPath, state);\n transactionHandled.add(relPath);\n }\n for (const relPath of result.removedPaths) {\n nextBase.delete(relPath);\n transactionHandled.add(relPath);\n }\n }\n\n for (const relPath of unionPaths(baseMap, incomingMap, currentMap)) {\n const base = baseMap.get(relPath);\n const incoming = incomingMap.get(relPath);\n const currentEntry = currentMap.get(relPath);\n\n if (deferredPaths.has(relPath)) {\n if (base) nextBase.set(relPath, base);\n else nextBase.delete(relPath);\n skipped += 1;\n continue;\n }\n\n // The generation transaction already published or removed this path and\n // applied its nextBase bookkeeping above; nothing left to do.\n if (transactionHandled.has(relPath)) continue;\n\n // A deferral anywhere in a generation defers the WHOLE generation: no\n // partial replacement in either direction, local files and base entries\n // stay exactly as they are.\n const membership = embeddingGenerationMembership(relPath);\n if (membership && deferredGenerationDirs.has(membership.shardDir)) {\n if (base) nextBase.set(relPath, base);\n else nextBase.delete(relPath);\n skipped += 1;\n continue;\n }\n\n if (incoming) {\n if (currentEntry?.sha256 === incoming.sha256) {\n if (await setSafeFileMtime(root, relPath, incoming.mtimeMs)) {\n nextBase.set(relPath, toFileState(incoming));\n } else {\n if (base) nextBase.set(relPath, base);\n else nextBase.delete(relPath);\n pendingLocal += 1;\n }\n skipped += 1;\n continue;\n }\n // Remote unchanged from the shared base while the local file drifted:\n // keep the local copy (no content is needed to make that decision).\n // Members of a replaced generation never reach this branch — the\n // generation transaction or the deferral guard handled them above.\n if (\n shouldPreferIncomingOfflineRuntimeFile(relPath) &&\n currentEntry && base && incoming.sha256 === base.sha256\n ) {\n nextBase.set(relPath, base);\n skipped += 1;\n continue;\n }\n if (shouldPreferIncomingOfflineRuntimeFile(relPath)) {\n await writeSafeFile(root, relPath, requiredBuffer(incomingBuffers, relPath), options.writeFile, incoming.mtimeMs);\n nextBase.set(relPath, toFileState(incoming));\n upserted += 1;\n continue;\n }\n if (!currentEntry && base && incoming.sha256 === base.sha256) {\n nextBase.set(relPath, base);\n pendingLocal += 1;\n skipped += 1;\n continue;\n }\n if (!currentEntry && base && incoming.sha256 !== base.sha256) {\n conflicts.push(await recordConflict({\n root,\n relPath,\n reason: \"local_deleted_remote_modified\",\n baseSha256: base.sha256,\n incomingSha256: incoming.sha256,\n incomingBuffer: conflictIncomingBuffer(relPath),\n writeConflictCopies: options.writeConflictCopies !== false,\n sourceId: snapshot.sourceId,\n writeFile: options.writeFile,\n }));\n nextBase.set(relPath, base);\n continue;\n }\n if (!currentEntry && !base) {\n await writeSafeFile(root, relPath, requiredBuffer(incomingBuffers, relPath), options.writeFile, incoming.mtimeMs);\n nextBase.set(relPath, toFileState(incoming));\n upserted += 1;\n continue;\n }\n if (base && currentEntry && currentEntry.sha256 === base.sha256) {\n await writeSafeFile(root, relPath, requiredBuffer(incomingBuffers, relPath), options.writeFile, incoming.mtimeMs);\n nextBase.set(relPath, toFileState(incoming));\n upserted += 1;\n continue;\n }\n if (base && incoming.sha256 === base.sha256) {\n nextBase.set(relPath, base);\n pendingLocal += 1;\n skipped += 1;\n continue;\n }\n conflicts.push(await recordConflict({\n root,\n relPath,\n reason: base ? \"both_modified\" : \"remote_exists_for_local_create\",\n baseSha256: base?.sha256,\n localSha256: currentEntry?.sha256,\n incomingSha256: incoming.sha256,\n incomingBuffer: conflictIncomingBuffer(relPath),\n writeConflictCopies: options.writeConflictCopies !== false,\n sourceId: snapshot.sourceId,\n writeFile: options.writeFile,\n }));\n if (base) nextBase.set(relPath, base);\n continue;\n }\n\n // Node-local runtime state (#1786): a push-filtered remote snapshot\n // never carries these paths, so their absence is NOT a delete\n // instruction. Drop any stale base entry (pre-#1786 state files still\n // carry them) and leave the local file untouched — deleting a live\n // sqlite WAL/SHM here would corrupt the local LCM store.\n if (matchesOfflineSyncDefaultExclude(relPath)) {\n nextBase.delete(relPath);\n skipped += 1;\n continue;\n }\n if (!currentEntry) {\n nextBase.delete(relPath);\n skipped += 1;\n continue;\n }\n if (\n shouldPreferIncomingOfflineRuntimeFile(relPath) &&\n membership !== null && omittedGenerationDirs.has(membership.shardDir)\n ) {\n // The push omitted this whole generation because a filter excluded at\n // least one member (snapshot.omittedEmbeddingGenerationDirs): absence\n // is NOT a deletion — keep the local generation and its base entries\n // until it is pushed unfiltered or deleted with deletion metadata.\n pendingLocal += 1;\n skipped += 1;\n continue;\n }\n if (\n shouldPreferIncomingOfflineRuntimeFile(relPath) &&\n (base || shouldDeleteAbsentIncomingOfflineRuntimeFile(relPath))\n ) {\n await deleteSafeFile(\n root,\n relPath,\n options.deleteFile,\n deletionMtimeByPath?.get(relPath),\n );\n nextBase.delete(relPath);\n deleted += 1;\n continue;\n }\n if (shouldPreferIncomingOfflineRuntimeFile(relPath)) {\n pendingLocal += 1;\n skipped += 1;\n continue;\n }\n if (base && currentEntry.sha256 === base.sha256) {\n await deleteSafeFile(\n root,\n relPath,\n options.deleteFile,\n deletionMtimeByPath?.get(relPath),\n );\n nextBase.delete(relPath);\n deleted += 1;\n continue;\n }\n if (base) {\n conflicts.push({\n path: relPath,\n reason: \"local_modified_remote_deleted\",\n baseSha256: base.sha256,\n localSha256: currentEntry.sha256,\n });\n nextBase.set(relPath, base);\n continue;\n }\n pendingLocal += 1;\n skipped += 1;\n }\n\n return {\n upserted: upserted + generationUpserted,\n deleted: deleted + generationDeleted,\n skipped,\n pendingLocal,\n conflicts,\n nextBaseFiles: [...nextBase.values()].sort(compareByPath),\n };\n}\n\nexport async function applyOfflineSyncChangeset(options: {\n root: string;\n changeset: unknown;\n currentFiles?: readonly OfflineSyncFileState[];\n returnCurrentFiles?: boolean;\n writeConflictCopies?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n writeFile?: (target: OfflineSyncFileWriteTarget) => Promise<void>;\n writeStagingFile?: (target: OfflineSyncFileStagingWriteTarget) => Promise<void>;\n readStagingFile?: (target: OfflineSyncFileStagingReadTarget) => Promise<Buffer>;\n deleteFile?: (target: OfflineSyncFileDeleteTarget) => Promise<void>;\n recordDeletionRevision?: OfflineSyncRecordDeletionRevision;\n}): Promise<OfflineSyncApplyChangesetResult> {\n let changeset: OfflineSyncChangeset;\n try {\n changeset = normalizeOfflineSyncChangeset(options.changeset);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(\n message.startsWith(\"offline sync\")\n ? message\n : `offline sync changeset invalid: ${message}`,\n );\n }\n const root = await ensureSyncRoot(options.root, \"applyOfflineSyncChangeset\");\n const records = changeset.changes\n .filter((change): change is Extract<OfflineSyncChange, { type: \"upsert\" }> => change.type === \"upsert\")\n .map((change) => change.file);\n const incomingBuffers = await verifyRecordContents(records, \"offline sync changeset\");\n const currentFiles = options.currentFiles\n ? filterBaseFilesForMode(normalizeFileStates(options.currentFiles), changeset.includeTranscripts).sort(compareByPath)\n : (await buildOfflineSyncSnapshotForPaths({\n root: root.abs,\n sourceId: \"local\",\n paths: changeset.changes.map((change) => change.path),\n includeContent: false,\n includeTranscripts: changeset.includeTranscripts,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n excludeNodeLocalState: false,\n })).files;\n const currentMap = byPath(currentFiles);\n const conflicts: OfflineSyncConflict[] = [];\n let appliedUpserts = 0;\n let appliedDeletes = 0;\n let skipped = 0;\n\n // Embedding generations apply as ONE unit through the shared locked\n // transaction (issue #3150). Deferred generations surface as conflicts so\n // the push side never checkpoints them as applied.\n const generationRouting = await applyChangesetEmbeddingGenerations({\n root,\n changeset,\n incomingBuffers,\n currentMap,\n io: {\n readFile: options.readFile,\n writeStagingFile: options.writeStagingFile,\n readStagingFile: options.readStagingFile,\n deleteFile: options.deleteFile,\n },\n customIoPresent: Boolean(options.writeFile || options.readFile || options.readFileDigest || options.deleteFile),\n now: Date.now(),\n });\n appliedUpserts += generationRouting.appliedUpserts;\n appliedDeletes += generationRouting.appliedDeletes;\n conflicts.push(...generationRouting.conflicts);\n\n for (const change of changeset.changes) {\n if (generationRouting.conflictedPaths.has(change.path)) continue;\n if (generationRouting.transactionHandled.has(change.path)) continue;\n const currentEntry = currentMap.get(change.path);\n if (change.type === \"upsert\") {\n if (currentEntry?.sha256 === change.file.sha256) {\n if (await setSafeFileMtime(root, change.path, change.file.mtimeMs)) {\n skipped += 1;\n } else {\n await writeSafeFile(root, change.path, requiredBuffer(incomingBuffers, change.path), options.writeFile, change.file.mtimeMs);\n currentMap.set(change.path, toFileState(change.file));\n appliedUpserts += 1;\n }\n continue;\n }\n if (!change.baseSha256) {\n if (!currentEntry) {\n await writeSafeFile(root, change.path, requiredBuffer(incomingBuffers, change.path), options.writeFile, change.file.mtimeMs);\n currentMap.set(change.path, toFileState(change.file));\n appliedUpserts += 1;\n continue;\n }\n conflicts.push(await recordConflict({\n root,\n relPath: change.path,\n reason: \"remote_exists_for_local_create\",\n localSha256: currentEntry.sha256,\n incomingSha256: change.file.sha256,\n incomingBuffer: incomingBuffers.get(change.path),\n writeConflictCopies: options.writeConflictCopies !== false,\n sourceId: changeset.sourceId,\n writeFile: options.writeFile,\n }));\n continue;\n }\n if (currentEntry?.sha256 === change.baseSha256) {\n await writeSafeFile(root, change.path, requiredBuffer(incomingBuffers, change.path), options.writeFile, change.file.mtimeMs);\n currentMap.set(change.path, toFileState(change.file));\n appliedUpserts += 1;\n continue;\n }\n conflicts.push(await recordConflict({\n root,\n relPath: change.path,\n reason: currentEntry ? \"remote_changed_for_local_update\" : \"remote_deleted_for_local_update\",\n baseSha256: change.baseSha256,\n localSha256: currentEntry?.sha256,\n incomingSha256: change.file.sha256,\n incomingBuffer: incomingBuffers.get(change.path),\n writeConflictCopies: options.writeConflictCopies !== false,\n sourceId: changeset.sourceId,\n writeFile: options.writeFile,\n }));\n continue;\n }\n\n if (!currentEntry) {\n if (change.mtimeMs !== undefined && options.recordDeletionRevision) {\n await options.recordDeletionRevision({\n root: root.abs,\n path: change.path,\n filePath: await resolveSafeArchiveTarget(root, change.path),\n mtimeMs: change.mtimeMs,\n });\n }\n skipped += 1;\n continue;\n }\n if (currentEntry.sha256 === change.baseSha256) {\n await deleteSafeFile(root, change.path, options.deleteFile, change.mtimeMs);\n currentMap.delete(change.path);\n appliedDeletes += 1;\n continue;\n }\n conflicts.push({\n path: change.path,\n reason: \"remote_changed_for_local_delete\",\n baseSha256: change.baseSha256,\n localSha256: currentEntry.sha256,\n });\n }\n\n // Generation transactions bypassed the per-file loop; fold their published\n // and removed members into the partial result map (returnCurrentFiles ===\n // false consumers) so it reflects the post-apply generation exactly.\n for (const [relPath, state] of generationRouting.writtenStates) currentMap.set(relPath, state);\n for (const relPath of generationRouting.removedPaths) currentMap.delete(relPath);\n\n return {\n appliedUpserts,\n appliedDeletes,\n skipped,\n conflicts,\n currentFiles: options.returnCurrentFiles === false\n ? [...currentMap.values()].sort(compareByPath)\n : (await buildOfflineSyncSnapshot({\n root: root.abs,\n sourceId: \"local\",\n includeContent: false,\n includeTranscripts: changeset.includeTranscripts,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n excludeNodeLocalState: false,\n })).files,\n ...(options.returnCurrentFiles === false ? { currentFilesComplete: false } : {}),\n };\n}\n\nasync function verifyRecordContents(\n records: readonly OfflineSyncFileRecord[],\n context: string,\n options: {\n requireContent?: boolean;\n readIncomingFile?: (target: { path: string; sha256: string; bytes: number }) => Promise<Buffer | null>;\n } = {},\n): Promise<Map<string, Buffer>> {\n const buffers = new Map<string, Buffer>();\n for (const record of records) {\n if (typeof record.contentBase64 !== \"string\") {\n if (options.readIncomingFile) {\n // Explicit INCOMING content source for records whose bytes travel\n // out-of-band (chunked fetch into the client's private staging\n // root). Never the local current-state file: the buffer is\n // digest-verified against the incoming record before anything is\n // published. null keeps the metadata-only behavior below.\n const incoming = await options.readIncomingFile({\n path: record.path,\n sha256: record.sha256,\n bytes: record.bytes,\n });\n if (incoming) {\n const digest = sha256Buffer(incoming);\n if (digest.sha256 !== record.sha256 || digest.bytes !== record.bytes) {\n throw new Error(`${context}: incoming content checksum mismatch for ${record.path}`);\n }\n buffers.set(record.path, incoming);\n continue;\n }\n }\n if (options.requireContent === false) continue;\n throw new Error(`${context}: contentBase64 is required for ${record.path}`);\n }\n const buffer = Buffer.from(record.contentBase64, \"base64\");\n const digest = sha256Buffer(buffer);\n if (digest.sha256 !== record.sha256 || digest.bytes !== record.bytes) {\n throw new Error(\n `${context}: content checksum mismatch for ${record.path}`,\n );\n }\n buffers.set(record.path, buffer);\n }\n return buffers;\n}\n\nfunction requiredBuffer(buffers: Map<string, Buffer>, relPath: string): Buffer {\n const buffer = buffers.get(relPath);\n if (!buffer) {\n throw new Error(`missing decoded content for ${relPath}`);\n }\n return buffer;\n}\n\nasync function ensureSyncRoot(rootPath: string, errorPrefix: string): Promise<SafeArchiveRoot> {\n const rootAbs = path.resolve(rootPath);\n await mkdir(rootAbs, { recursive: true });\n return prepareSafeArchiveRoot(rootAbs, errorPrefix, \"root\");\n}\n\nfunction byPath<T extends OfflineSyncFileState>(files: readonly T[]): Map<string, T> {\n const out = new Map<string, T>();\n for (const file of files) {\n out.set(validateArchiveRelativePath(file.path, \"offlineSync\"), file);\n }\n return out;\n}\n\nfunction unionPaths(...maps: Array<Map<string, unknown>>): string[] {\n const paths = new Set<string>();\n for (const map of maps) {\n for (const key of map.keys()) paths.add(key);\n }\n return [...paths].sort();\n}\n\nfunction toFileState(file: OfflineSyncFileState): OfflineSyncFileState {\n return {\n path: file.path,\n sha256: file.sha256,\n bytes: file.bytes,\n mtimeMs: file.mtimeMs,\n };\n}\n\nasync function writeSafeFile(\n root: SafeArchiveRoot,\n relPath: string,\n content: Buffer,\n writeFileHook?: (target: OfflineSyncFileWriteTarget) => Promise<void>,\n mtimeMs?: number,\n): Promise<void> {\n const target = await resolveSafeArchiveTarget(root, relPath);\n if (writeFileHook) {\n await writeFileHook({ root: root.abs, path: relPath, filePath: target, content });\n await setSafeFileMtime(root, relPath, mtimeMs);\n return;\n }\n await mkdir(path.dirname(target), { recursive: true });\n const tmp = path.join(\n path.dirname(target),\n `.remnic-sync.${process.pid}.${randomUUID()}.tmp`,\n );\n await writeFile(tmp, content);\n try {\n const targetStat = await lstat(target).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n });\n if (targetStat?.isSymbolicLink()) {\n throw new Error(`offline sync target is a symlink: ${relPath}`);\n }\n await rename(tmp, target);\n await setSafeFileMtime(root, relPath, mtimeMs);\n } catch (error) {\n await unlink(tmp).catch(() => {});\n throw error;\n }\n}\n\n\n/**\n * Read the local file digest for a single relative path without applying\n * push-side exclude rules. Used by apply-side helpers that need to check\n * the current local state of a path that the push-side exclude would\n * reject (e.g. `state/lcm.sqlite`). Returns `null` if the file does not\n * exist, is not a regular file, or is a symlink.\n */\nasync function readLocalFileState(options: {\n rootAbs: string;\n relPath: string;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n signal?: AbortSignal;\n}): Promise<OfflineSyncFileState | null> {\n const filePath = await resolveSafeArchiveTarget(\n await prepareSafeArchiveRoot(options.rootAbs, \"readLocalFileState\", \"rootAbs\"),\n options.relPath,\n );\n const st = await lstat(filePath).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n });\n if (!st || st.isSymbolicLink() || !st.isFile()) return null;\n throwIfOfflineSyncAborted(options.signal);\n let digest: OfflineSyncFileDigest;\n if (options.readFileDigest) {\n digest = await options.readFileDigest({ root: options.rootAbs, path: options.relPath, filePath });\n } else if (options.readFile) {\n const content = await options.readFile({ root: options.rootAbs, path: options.relPath, filePath });\n digest = sha256Buffer(content);\n } else {\n digest = await sha256OfflineSyncFile(filePath, options.signal);\n }\n throwIfOfflineSyncAborted(options.signal);\n return {\n path: options.relPath,\n sha256: digest.sha256,\n bytes: digest.bytes,\n mtimeMs: st.mtimeMs,\n };\n}\n\nexport async function applyOfflineSyncFileContentChunk(options: {\n root: string;\n sourceId: string;\n path: string;\n sha256: string;\n bytes: number;\n mtimeMs: number;\n offset?: number;\n content: Buffer;\n baseSha256?: string;\n includeTranscripts?: boolean;\n readFile?: (target: OfflineSyncFileTarget) => Promise<Buffer>;\n readFileDigest?: (target: OfflineSyncFileTarget) => Promise<OfflineSyncFileDigest>;\n writeFile?: (target: OfflineSyncFileWriteTarget) => Promise<void>;\n writeStagingFile?: (target: OfflineSyncFileStagingWriteTarget) => Promise<void>;\n writeFileChunks?: (target: OfflineSyncFileWriteChunksTarget) => Promise<void>;\n}): Promise<OfflineSyncApplyFileContentChunkResult> {\n const root = await ensureSyncRoot(options.root, \"applyOfflineSyncFileContentChunk\");\n const sourceId = normalizeSourceId(options.sourceId, \"sourceId\");\n const relPath = normalizeRelativePath(options.path, \"path\");\n const includeTranscripts = options.includeTranscripts !== false;\n if (shouldExcludeRelPath(relPath, includeTranscripts)) {\n throw new Error(`offline sync file content path is excluded: ${relPath}`);\n }\n const sha256 = assertSha256(options.sha256, \"sha256\");\n const bytes = assertNonNegativeInteger(options.bytes, \"bytes\");\n const mtimeMs = assertOfflineSyncMtimeMs(options.mtimeMs, \"mtimeMs\");\n const offset = options.offset === undefined\n ? 0\n : assertNonNegativeInteger(options.offset, \"offset\");\n const baseSha256 = options.baseSha256 === undefined\n ? undefined\n : assertSha256(options.baseSha256, \"baseSha256\");\n const preferIncomingRuntimeFile = shouldPreferIncomingOfflineRuntimeFile(relPath);\n if (!Buffer.isBuffer(options.content)) {\n throw new Error(\"content must be a Buffer\");\n }\n if (options.content.length > OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES) {\n throw new Error(\n `content chunk must be ${OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES} bytes or fewer`,\n );\n }\n if (bytes > 0 && options.content.length === 0) {\n throw new Error(\"content chunk must be non-empty before EOF\");\n }\n if (offset > bytes || offset + options.content.length > bytes) {\n throw new Error(`content chunk range exceeds declared file size for ${relPath}`);\n }\n if (options.writeFile && !options.writeFileChunks) {\n throw new Error(\"offline sync upload storage hooks require writeFileChunks\");\n }\n if (options.writeFile && !options.writeStagingFile) {\n throw new Error(\"offline sync upload storage hooks require writeStagingFile\");\n }\n const baseResult = {\n path: relPath,\n sha256,\n bytes,\n mtimeMs,\n offset,\n chunkBytes: options.content.length,\n done: offset + options.content.length === bytes,\n };\n const currentFileConflict = async (\n currentFile: OfflineSyncFileState | undefined,\n ): Promise<{ conflict: OfflineSyncConflict; currentFile?: OfflineSyncFileState } | null> => {\n if (!baseSha256 && currentFile && !preferIncomingRuntimeFile) {\n const conflict = await recordConflict({\n root,\n relPath,\n reason: \"remote_exists_for_local_create\",\n localSha256: currentFile.sha256,\n incomingSha256: sha256,\n writeConflictCopies: false,\n sourceId,\n writeFile: options.writeFile,\n });\n return {\n conflict,\n currentFile,\n };\n }\n if (baseSha256 && currentFile?.sha256 !== baseSha256 && !preferIncomingRuntimeFile) {\n const conflict = await recordConflict({\n root,\n relPath,\n reason: currentFile ? \"remote_changed_for_local_update\" : \"remote_deleted_for_local_update\",\n baseSha256,\n localSha256: currentFile?.sha256,\n incomingSha256: sha256,\n writeConflictCopies: false,\n sourceId,\n writeFile: options.writeFile,\n });\n return {\n conflict,\n ...(currentFile ? { currentFile } : {}),\n };\n }\n return null;\n };\n if (offset === 0) {\n await pruneOfflineUploadStaging(root);\n const currentFile = await readLocalFileState({\n rootAbs: root.abs,\n relPath,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n });\n if (currentFile && currentFile.sha256 === sha256) {\n await setSafeFileMtime(root, relPath, mtimeMs);\n return {\n ...baseResult,\n done: true,\n chunkBytes: 0,\n applied: false,\n skipped: true,\n currentFile: toFileState(currentFile),\n };\n }\n const conflictResult = await currentFileConflict(currentFile ? toFileState(currentFile) : undefined);\n if (conflictResult) {\n return {\n ...baseResult,\n done: true,\n chunkBytes: 0,\n applied: false,\n skipped: false,\n ...conflictResult,\n };\n }\n }\n\n const upload = await writeOfflineUploadChunk({\n root,\n sourceId,\n relPath,\n sha256,\n bytes,\n offset,\n content: options.content,\n readFile: options.readFile,\n writeFile: options.writeFile,\n writeStagingFile: options.writeStagingFile,\n });\n const done = baseResult.done;\n if (!done) {\n return {\n ...baseResult,\n applied: false,\n skipped: false,\n };\n }\n\n const digest = await digestOfflineUploadStagingContent({\n root,\n upload,\n readFile: options.readFile,\n });\n if (digest.sha256 !== sha256 || digest.bytes !== bytes) {\n await cleanupOfflineUpload(upload).catch(() => {});\n throw new Error(`offline sync upload checksum mismatch for ${relPath}`);\n }\n\n const currentFile = await readLocalFileState({\n rootAbs: root.abs,\n relPath,\n readFile: options.readFile,\n readFileDigest: options.readFileDigest,\n });\n const uploadedState: OfflineSyncFileState = {\n path: relPath,\n sha256,\n bytes,\n mtimeMs,\n };\n\n try {\n if (currentFile && currentFile.sha256 === sha256) {\n await setSafeFileMtime(root, relPath, mtimeMs);\n return {\n ...baseResult,\n applied: false,\n skipped: true,\n currentFile: uploadedState,\n };\n }\n\n const conflictResult = await currentFileConflict(currentFile ? toFileState(currentFile) : undefined);\n if (conflictResult) {\n return {\n ...baseResult,\n applied: false,\n skipped: false,\n ...conflictResult,\n };\n }\n\n await writeSafeFileFromUpload(root, relPath, upload, options.readFile, options.writeFileChunks, mtimeMs);\n return {\n ...baseResult,\n applied: true,\n skipped: false,\n currentFile: uploadedState,\n };\n } finally {\n await cleanupOfflineUpload(upload).catch(() => {});\n }\n}\n\n\nasync function deleteSafeFile(\n root: SafeArchiveRoot,\n relPath: string,\n deleteFile?: (target: OfflineSyncFileDeleteTarget) => Promise<void>,\n mtimeMs?: number,\n): Promise<void> {\n const target = await resolveSafeArchiveTarget(root, relPath);\n if (deleteFile) {\n await deleteFile({\n root: root.abs,\n path: relPath,\n filePath: target,\n ...(mtimeMs === undefined ? {} : { mtimeMs }),\n });\n return;\n }\n await unlink(target).catch((error: unknown) => {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw error;\n });\n}\n\nasync function recordConflict(options: {\n root: SafeArchiveRoot;\n relPath: string;\n reason: OfflineSyncConflict[\"reason\"];\n baseSha256?: string;\n localSha256?: string;\n incomingSha256?: string;\n incomingBuffer?: Buffer;\n writeConflictCopies: boolean;\n sourceId: string;\n writeFile?: (target: OfflineSyncFileWriteTarget) => Promise<void>;\n}): Promise<OfflineSyncConflict> {\n let conflictPath: string | undefined;\n if (options.writeConflictCopies && options.incomingBuffer) {\n const sourceHash = hashText(options.sourceId).slice(0, 12);\n const stamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n conflictPath = `${SYNC_INTERNAL_DIR}/conflicts/${stamp}-${sourceHash}/${options.relPath}`;\n await writeSafeFile(options.root, conflictPath, options.incomingBuffer, options.writeFile);\n }\n return {\n path: options.relPath,\n reason: options.reason,\n baseSha256: options.baseSha256,\n localSha256: options.localSha256,\n incomingSha256: options.incomingSha256,\n ...(conflictPath ? { conflictPath } : {}),\n };\n}\n\nexport function defaultOfflineSyncStatePath(\n memoryDir: string,\n remoteId: string,\n namespace?: string,\n): string {\n const key = hashText(`${remoteId}\\0${namespace ?? \"\"}`).slice(0, 16);\n return path.join(path.resolve(memoryDir), SYNC_INTERNAL_DIR, \"state\", `${key}.json`);\n}\n\nexport async function readOfflineSyncState(\n statePath: string,\n): Promise<OfflineSyncState | null> {\n let raw: string;\n try {\n raw = await readFile(path.resolve(statePath), \"utf-8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw error;\n }\n const parsed = JSON.parse(raw) as unknown;\n return normalizeOfflineSyncState(parsed);\n}\n\nexport async function writeOfflineSyncState(\n statePath: string,\n state: OfflineSyncState,\n): Promise<void> {\n const normalized = normalizeOfflineSyncState(state);\n const target = path.resolve(statePath);\n await mkdir(path.dirname(target), { recursive: true });\n const tmp = path.join(\n path.dirname(target),\n `.remnic-sync-state.${process.pid}.${randomUUID()}.tmp`,\n );\n await writeFile(tmp, JSON.stringify(normalized, null, 2) + \"\\n\", \"utf-8\");\n try {\n await rename(tmp, target);\n } catch (error) {\n await unlink(tmp).catch(() => {});\n throw error;\n }\n}\n\nexport function offlineSyncStateFromSnapshot(options: {\n remoteId: string;\n namespace?: string;\n snapshot: OfflineSyncSnapshot;\n baseFiles?: readonly OfflineSyncFileState[];\n}): OfflineSyncState {\n const snapshot = normalizeOfflineSyncSnapshot(options.snapshot);\n return normalizeOfflineSyncState({\n version: OFFLINE_SYNC_STATE_VERSION,\n remoteId: options.remoteId,\n namespace: options.namespace,\n includeTranscripts: snapshot.includeTranscripts,\n lastSyncedAt: new Date().toISOString(),\n baseFiles: options.baseFiles ?? snapshot.files.map(toFileState),\n });\n}\n\nexport function normalizeOfflineSyncState(input: unknown): OfflineSyncState {\n if (!input || typeof input !== \"object\" || Array.isArray(input)) {\n throw new Error(\"offline sync state must be an object\");\n }\n const obj = input as Record<string, unknown>;\n if (obj.version !== OFFLINE_SYNC_STATE_VERSION) {\n throw new Error(`offline sync state version must be ${OFFLINE_SYNC_STATE_VERSION}`);\n }\n const namespace =\n typeof obj.namespace === \"string\" && obj.namespace.trim().length > 0\n ? obj.namespace.trim()\n : undefined;\n const baseFiles = normalizeFileStates(obj.baseFiles as readonly unknown[] | undefined)\n .sort(compareByPath);\n assertUniquePaths(baseFiles, \"offline sync state\");\n return {\n version: OFFLINE_SYNC_STATE_VERSION,\n remoteId: normalizeSourceId(obj.remoteId, \"remoteId\"),\n ...(namespace ? { namespace } : {}),\n includeTranscripts: assertBoolean(obj.includeTranscripts, \"includeTranscripts\"),\n lastSyncedAt: normalizeIsoString(obj.lastSyncedAt, \"lastSyncedAt\"),\n baseFiles,\n };\n}\n\nexport function fileStatesFromSnapshot(snapshot: OfflineSyncSnapshot): OfflineSyncFileState[] {\n return normalizeOfflineSyncSnapshot(snapshot).files.map(toFileState).sort(compareByPath);\n}\n"],"mappings":"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","names":["chunk","digest","currentFile"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/embedding-index-storage.ts"],"sourcesContent":["/**\n * File-level storage for the embedding fallback index (issue #3146).\n *\n * Two single-generation layouts, exactly one authoritative at a time:\n * - `legacy`: the single `state/embeddings.json` file, used while the\n * whole index serializes within `resolveIndexFileCharLimit()` chars;\n * - `sharded`: the published `state/embeddings/` directory of hash-assigned\n * shard files, migrated to ONE-WAY and ATOMICALLY (stage a complete shard\n * set, publish with a single directory rename, demote the legacy file to\n * a non-authoritative recovery artifact). Generations never merge, so a\n * crash cannot resurrect deleted entries or drop published ones.\n *\n * This module owns files, budgets, and durable diagnostics only — no index\n * caching or provider logic (that lives in `embedding-fallback.ts`).\n */\nimport path from \"node:path\";\nimport { constants as bufferConstants } from \"node:buffer\";\nimport { lstat, mkdir, mkdtemp, realpath, readFile, readdir, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { log } from \"./logger.js\";\nimport { readEnvVar } from \"./runtime/env.js\";\nimport type { EmbeddingGenerationFence } from \"./embedding-generation-lock.js\";\n\nexport type EmbeddingProviderType = \"openai\" | \"local\" | \"host\";\n\nexport type EmbeddingIndexEntry = {\n vector: number[];\n path: string;\n};\n\nexport type EmbeddingIndexFile = {\n version: 1;\n provider: EmbeddingProviderType;\n model: string;\n entries: Record<string, EmbeddingIndexEntry>;\n};\n\nexport type EmbeddingIndexIdentity = Pick<EmbeddingIndexFile, \"provider\" | \"model\">;\n\n/** Outcome of reading one managed index file (legacy or shard). */\nexport type ManagedIndexRead =\n | { outcome: \"ok\"; file: EmbeddingIndexFile }\n | { outcome: \"absent\" }\n | { outcome: \"foreign\" }\n | { outcome: \"unreadable\"; reason: string };\n\n/** Which generation owns the index right now. */\nexport type IndexLayout = \"empty\" | \"legacy\" | \"sharded\";\n\n/**\n * Thrown when an embedding index (or one of its shards) cannot be persisted\n * within the per-file serialization budget. Issue #3146: index files are\n * materialized as single V8 strings, so a JSON document at or past\n * `bufferConstants.MAX_STRING_LENGTH` chars makes every read and write throw\n * `RangeError: Invalid string length`. The index is sharded before that\n * ceiling; this tagged error is reserved for the residual case where even\n * one shard cannot hold the payload (e.g. a single entry with an enormous\n * vector), so callers can classify it as recoverable-with-record instead of\n * an opaque background failure.\n */\nexport class EmbeddingIndexCapacityError extends Error {\n override readonly name = \"EmbeddingIndexCapacityError\" as const;\n constructor(\n message: string,\n readonly memoryId?: string,\n ) {\n super(message);\n }\n}\n\n/**\n * Thrown when an index file that should be authoritative cannot be read\n * (I/O error, over-budget size, unparseable JSON). Mutation paths fail\n * CLOSED on this: they must not continue with a fresh empty index and\n * pretend the previous vectors were loaded — the file is left untouched in\n * place for recovery. Read-only paths (recall) fail open to empty results\n * and record the reason durably.\n */\nexport class EmbeddingIndexStorageError extends Error {\n override readonly name = \"EmbeddingIndexStorageError\" as const;\n}\n\n/** Durable diagnostic row describing the last failed embedding-index write. */\nexport interface EmbeddingIndexWriteFailure {\n ts: string;\n kind: \"capacity\" | \"io\";\n message: string;\n memoryId?: string;\n}\n\n/**\n * Durable embedding-index diagnostics (issue #3146), persisted at\n * `<memoryDir>/state/embedding-fallback-status.json` and surfaced through\n * console_state, so background ingestion failures are visible to operators\n * instead of only ever appearing as log lines.\n */\nexport interface EmbeddingIndexStatusFile {\n version: 1;\n /** Cumulative count of failed index writes since the file was created. */\n failureCount: number;\n /** Active write failure; cleared by the next successful save. */\n lastWriteFailure?: EmbeddingIndexWriteFailure;\n /** Set when an unreadable index file was detected instead of overwritten. */\n lastReadRecovery?: { ts: string; message: string };\n lastSuccessAt?: string;\n}\n\n/**\n * Per-file serialization budget (JSON-string chars) for WRITES of the legacy\n * `state/embeddings.json` file and of every shard under `state/embeddings/`.\n * The 16MiB margin keeps the write round-trip clear of the V8 single-string\n * ceiling even with UTF-8 byte/count skew and small header growth. Override\n * per environment (tests, headroom tuning) via\n * `REMNIC_EMBEDDING_INDEX_FILE_CHAR_LIMIT`.\n *\n * READS are gated by the HARD ceiling (`resolveIndexHardReadCharLimit`),\n * never by this budget: a legacy index written by an older version may\n * legitimately sit between the soft budget and the hard ceiling (the\n * reported production file does), and it must still load and migrate.\n */\nconst DEFAULT_INDEX_FILE_CHAR_LIMIT =\n bufferConstants.MAX_STRING_LENGTH - 16 * 1024 * 1024;\n\n/**\n * Hard single-string ceiling for READS: files at or above this size are not\n * attempted (a readFile would throw `RangeError: Invalid string length`);\n * their bytes are preserved in place and mutations fail closed with an\n * actionable error. Defaults to the V8 maximum; tests inject a small value\n * via `REMNIC_EMBEDDING_INDEX_HARD_READ_LIMIT_CHARS`.\n */\nfunction resolveIndexHardReadCharLimit(): number {\n const soft = resolveIndexFileCharLimit();\n const raw = readEnvVar(\"REMNIC_EMBEDDING_INDEX_HARD_READ_LIMIT_CHARS\");\n if (raw) {\n const parsed = Number(raw);\n if (Number.isInteger(parsed) && parsed >= soft) return parsed;\n }\n return bufferConstants.MAX_STRING_LENGTH;\n}\n\n/** Hash shards under `state/embeddings/` used once the budget is exceeded. */\nconst SHARD_COUNT = 64;\n\nconst SHARD_FILE_PATTERN = /^shard-\\d{4}\\.json$/;\n\nexport function resolveIndexFileCharLimit(): number {\n const raw = readEnvVar(\"REMNIC_EMBEDDING_INDEX_FILE_CHAR_LIMIT\");\n if (raw) {\n const parsed = Number(raw);\n if (Number.isInteger(parsed) && parsed >= 1024) return parsed;\n }\n return DEFAULT_INDEX_FILE_CHAR_LIMIT;\n}\n\nfunction shardFileName(shardIndex: number): string {\n return `shard-${String(shardIndex).padStart(4, \"0\")}.json`;\n}\n\n/**\n * Fixed transaction backup path for identity replacements. A fixed (not\n * per-process) name is what makes the rename gap recoverable: whatever\n * process restarts after a crash finds the demoted former generation here\n * and rolls it back into place.\n */\nfunction replacementBackupPath(shardDir: string): string {\n return path.join(path.dirname(shardDir), \"embeddings.pre-replace.tmp\");\n}\n\n/**\n * Stable FNV-1a shard assignment: an entry always hashes to the same shard,\n * so an update or removal never needs a manifest to find its file.\n */\nexport function shardIndexOf(memoryId: string, shardCount: number): number {\n let hash = 0x811c9dc5;\n for (let i = 0; i < memoryId.length; i++) {\n hash ^= memoryId.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193) >>> 0;\n }\n return hash % shardCount;\n}\n\n/**\n * A shard file named `shard-NNNN.json` must only contain ids that hash to\n * that shard: a misplaced copy would be loaded today and silently resurrect\n * stale vectors after the computed shard is rewritten (issue #3148, round 6).\n * Throws the tagged storage error so mutations fail closed and recall fails\n * open at its boundary.\n */\nexport function validateShardMembership(shardName: string, file: EmbeddingIndexFile): void {\n const match = /^shard-(\\d{4})\\.json$/.exec(shardName);\n if (!match) return; // not a shard file (legacy documents have no constraint)\n const shardIndex = Number(match[1]);\n for (const id of Object.keys(file.entries)) {\n if (shardIndexOf(id, SHARD_COUNT) !== shardIndex) {\n throw new EmbeddingIndexStorageError(\n `refusing embedding index shard ${shardName}: id ${id} hashes to shard ${shardIndexOf(id, SHARD_COUNT)}, not ${shardIndex}; file preserved in place`,\n );\n }\n }\n}\n\nexport function isInvalidStringLengthError(err: unknown): boolean {\n return err instanceof RangeError && /invalid string length/i.test(err.message);\n}\n\n/**\n * Parse and FULLY validate one serialized index document (legacy or shard).\n * The single read boundary shared by disk reads and offline-sync pulls: a\n * document with a valid header but a malformed body (`entries` not a plain\n * record, or an entry whose `path` is not a string / whose `vector` is not a\n * finite-number array) is `unreadable`, not `ok` — recall fails open on the\n * tagged reason, mutations fail closed, and the bytes are never overwritten\n * (issue #3148 review, round 4).\n */\nexport function parseEmbeddingIndexDocument(raw: string): ManagedIndexRead {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n return {\n outcome: \"unreadable\",\n reason: `JSON parse failed: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n Array.isArray(parsed) ||\n (parsed as Partial<EmbeddingIndexFile>).version !== 1 ||\n typeof (parsed as Partial<EmbeddingIndexFile>).provider !== \"string\" ||\n typeof (parsed as Partial<EmbeddingIndexFile>).model !== \"string\" ||\n ((parsed as Partial<EmbeddingIndexFile>).model as string).length === 0\n ) {\n return { outcome: \"foreign\" };\n }\n // An unsupported identity must fail closed like any other malformed\n // document: recall cannot serve it and mutations must not adopt it as\n // authoritative (issue #3148, round 6).\n if (\n (parsed as Partial<EmbeddingIndexFile>).provider !== \"openai\" &&\n (parsed as Partial<EmbeddingIndexFile>).provider !== \"local\" &&\n (parsed as Partial<EmbeddingIndexFile>).provider !== \"host\"\n ) {\n return { outcome: \"foreign\" };\n }\n const entries = (parsed as Partial<EmbeddingIndexFile>).entries;\n if (!entries || typeof entries !== \"object\" || Array.isArray(entries)) {\n return {\n outcome: \"unreadable\",\n reason: \"entries must be a plain record of memory id -> entry\",\n };\n }\n for (const [id, entry] of Object.entries(entries as Record<string, unknown>)) {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n return { outcome: \"unreadable\", reason: `entry ${id} must be an object` };\n }\n const candidate = entry as Partial<EmbeddingIndexEntry>;\n if (typeof candidate.path !== \"string\") {\n return { outcome: \"unreadable\", reason: `entry ${id}.path must be a string` };\n }\n if (!Array.isArray(candidate.vector)) {\n return { outcome: \"unreadable\", reason: `entry ${id}.vector must be an array` };\n }\n for (const component of candidate.vector) {\n if (!Number.isFinite(component)) {\n return {\n outcome: \"unreadable\",\n reason: `entry ${id}.vector must contain only finite numbers`,\n };\n }\n }\n }\n return { outcome: \"ok\", file: parsed as EmbeddingIndexFile };\n}\n\n/**\n * Group a complete index into per-shard entry records using the stable FNV\n * assignment. Shared by `persist()` and the offline-sync generation\n * transaction so a converted generation shards identically everywhere.\n */\nexport function shardEntriesForIndex(\n index: EmbeddingIndexFile,\n): Map<number, Record<string, EmbeddingIndexEntry>> {\n const groups = new Map<number, Record<string, EmbeddingIndexEntry>>();\n for (const id of Object.keys(index.entries)) {\n const shardIndex = shardIndexOf(id, SHARD_COUNT);\n const group = groups.get(shardIndex);\n if (group) group[id] = index.entries[id];\n else groups.set(shardIndex, { [id]: index.entries[id] });\n }\n return groups;\n}\n\n/**\n * Serialize one shard, translating a ceiling overflow into a tagged,\n * recoverable capacity error. Exported for the offline-sync generation\n * transaction, which stages incoming generations through the same budget.\n */\nexport function serializeEmbeddingShard(\n index: EmbeddingIndexFile,\n shardIndex: number,\n entries: Record<string, EmbeddingIndexEntry>,\n limit: number = resolveIndexFileCharLimit(),\n): string {\n let body: string;\n try {\n body = JSON.stringify({\n version: 1 as const,\n provider: index.provider,\n model: index.model,\n entries,\n });\n } catch (err) {\n throw new EmbeddingIndexCapacityError(\n `embedding index shard ${shardFileName(shardIndex)} exceeded the single-string ceiling while serializing: ${err instanceof Error ? err.message : String(err)}`,\n largestEntryId(entries) || undefined,\n );\n }\n if (body.length > limit) {\n const worstId = largestEntryId(entries);\n const worstLength = worstId && entries[worstId] ? JSON.stringify(entries[worstId]).length : 0;\n throw new EmbeddingIndexCapacityError(\n `embedding index shard ${shardFileName(shardIndex)} needs ${body.length} chars, over the ${limit}-char single-file limit; largest entry ${worstId || \"(unknown)\"} serializes to ${worstLength} chars`,\n worstId || undefined,\n );\n }\n return body;\n}\n\nfunction largestEntryId(entries: Record<string, EmbeddingIndexEntry>): string {\n let worstId = \"\";\n let worstLength = 0;\n for (const [id, entry] of Object.entries(entries)) {\n let length: number;\n try {\n length = JSON.stringify(entry).length;\n } catch {\n return id;\n }\n if (length > worstLength) {\n worstLength = length;\n worstId = id;\n }\n }\n return worstId;\n}\n\n/**\n * Optional canonical secure-store IO for the daemon. When provided (both\n * halves), file content is read/written through the SAME\n * StorageManager-backed contract offline sync uses: canonical-path AAD,\n * secure-key-aware, atomic. Shard STAGING writes carry the FINAL published\n * path so the post-publish rename keeps the ciphertext decryptable; dirty\n * shard, status, and legacy writes are their own canonical final path.\n * When omitted, the store behaves exactly as before (raw plaintext fs).\n * The diagnostics status file is intentionally ALWAYS plain: it holds no\n * memory content (failure strings/counts only) and console_state reads it\n * without unlocking the store.\n */\nexport interface EmbeddingIndexStoreIo {\n readUtf8(filePath: string): Promise<string>;\n writeUtf8(filePath: string, contents: string, opts?: { finalAadFilePath?: string }): Promise<void>;\n}\n\nexport class EmbeddingIndexFileStore {\n constructor(\n private readonly indexPath: string,\n private readonly shardDir: string,\n private readonly statusPath: string,\n private readonly io?: EmbeddingIndexStoreIo,\n ) {\n if (io && (Boolean(io.readUtf8) !== Boolean(io.writeUtf8))) {\n throw new EmbeddingIndexStorageError(\n \"embedding index store io requires both readUtf8 and writeUtf8; a half-wired io would mix encrypted and plaintext files\",\n );\n }\n }\n\n /** Legacy single-file layout path (public for error messages). */\n get legacyPath(): string {\n return this.indexPath;\n }\n\n /** Record an unreadable-authoritative-file reason (both read and mutation paths). */\n async recordIndexStatusForLoad(reason: string): Promise<void> {\n await this.recordIndexStatus({\n lastReadRecovery: { ts: new Date().toISOString(), message: reason },\n });\n }\n\n /**\n * Which generation owns the index right now. The published\n * `state/embeddings/` directory IS the layout marker: until it exists the\n * legacy file is authoritative; from the atomic rename onward it never\n * merges again.\n */\n async detectLayout(): Promise<IndexLayout> {\n // An interrupted identity replacement leaves the published directory\n // absent with the fixed transaction backup still on disk (the publish\n // rename never completed). Report SHARDED for that gap: the backup holds\n // the authoritative generation, so neither the legacy file nor a fresh\n // index may win, and reads fail open to empty until the mutation queue\n // performs the rollback. The rollback itself only ever runs inside\n // persist() — a write — so read paths never race an in-flight\n // replacement with a recovery rename (issue #3148 review).\n try {\n // lstat, NOT stat: a symlinked generation directory must be rejected\n // outright — following it would read or write OUTSIDE the state\n // directory through the link (codex PRRT_kwDORJXyws6mZ72r).\n const info = await lstat(this.shardDir);\n if (info.isSymbolicLink()) {\n throw new EmbeddingIndexStorageError(\n `embedding index shard directory is a symlink; refusing to read or write through it: ${this.shardDir}`,\n );\n }\n return \"sharded\";\n } catch (err) {\n if (err instanceof EmbeddingIndexStorageError) throw err;\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n // The pointer exists but cannot be stat'ed — fail towards the\n // published generation so its readers surface the I/O error.\n log.warn(`embedding index: shard dir stat failed (${err instanceof Error ? err.message : String(err)}); assuming sharded layout`);\n return \"sharded\";\n }\n if (await this.replacementBackupExists()) return \"sharded\";\n return this.legacyOrEmptyLayout();\n }\n }\n\n /**\n * Roll the fixed transaction backup back into the published position.\n * Returns true when a rollback happened.\n */\n private async replacementBackupExists(): Promise<boolean> {\n const backupPath = replacementBackupPath(this.shardDir);\n try {\n await stat(backupPath);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n // An unreadable backup must not be silently treated as absent —\n // that would permit the legacy fallback over a generation we cannot\n // inspect (issue #3148 review, round 1).\n throw new EmbeddingIndexStorageError(\n `cannot stat embedding index replacement backup ${backupPath}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n\n /**\n * The fixed transaction backup is a path with well-known semantics; a\n * planted symlink must never be restored into the published position (it\n * would point the generation outside the memory dir) nor removed through\n * as if it were the former generation. Symlinks are rejected outright.\n */\n private async assertBackupNotSymlink(backupPath: string): Promise<void> {\n const info = await lstat(backupPath).catch((err) => {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw err;\n });\n if (info?.isSymbolicLink()) {\n throw new EmbeddingIndexStorageError(\n `embedding index replacement backup is a symlink; refusing to touch it: ${backupPath}`,\n );\n }\n }\n\n /**\n * Mutation-queue entry point: roll the fixed transaction backup back into\n * the published position after an interrupted replacement. Returns true\n * when a rollback happened. Only fires in the actual rename gap\n * (published directory absent); callers must invalidate any cached index\n * view when this returns true.\n */\n async recoverIfInterrupted(fence?: EmbeddingGenerationFence): Promise<boolean> {\n // Only the rename gap (published directory absent) is recoverable. When\n // the directory is present - including after a crash that followed a\n // successful publish - the generation on disk is already authoritative\n // and renaming the backup onto it would fail with EEXIST (issue #3148\n // review, round 2).\n try {\n await stat(this.shardDir);\n return false;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n log.warn(`embedding index: recovery skipped because shard dir stat failed: ${err instanceof Error ? err.message : String(err)}`);\n return false;\n }\n }\n const backupPath = replacementBackupPath(this.shardDir);\n if (!(await this.replacementBackupExists())) return false;\n await this.assertBackupNotSymlink(backupPath);\n // The rollback rename is destructive: reassert lock ownership first.\n await fence?.();\n await rename(backupPath, this.shardDir);\n log.warn(\n `embedding index: recovered interrupted replacement; former generation restored from ${backupPath}`,\n );\n await this.recordIndexStatus({\n lastReadRecovery: {\n ts: new Date().toISOString(),\n message: \"interrupted identity replacement rolled back to the former generation\",\n },\n });\n return true;\n }\n\n private async legacyOrEmptyLayout(): Promise<IndexLayout> {\n try {\n await stat(this.indexPath);\n return \"legacy\";\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return \"empty\";\n throw err;\n }\n }\n\n /** Header identity of the authoritative generation, read leniently. */\n async identityFromDisk(): Promise<EmbeddingIndexIdentity | null> {\n const layout = await this.detectLayout();\n if (layout === \"sharded\") {\n // Shard files are bounded by the per-file budget, so the identity\n // probe never reads a ceiling-sized string.\n for (const name of await this.readShardNames()) {\n const read = await this.readFileAt(path.join(this.shardDir, name));\n if (read.outcome === \"ok\") {\n return { provider: read.file.provider, model: read.file.model };\n }\n }\n return null;\n }\n if (layout === \"legacy\") {\n const read = await this.readFileAt(this.indexPath);\n if (read.outcome === \"ok\") {\n return { provider: read.file.provider, model: read.file.model };\n }\n }\n return null;\n }\n\n /**\n * Load every readable shard into `merged`. Returns the generation identity.\n * Unreadable shards record durable diagnostics; `strict` additionally\n * fails the mutation closed.\n */\n async readShardGenerationInto(\n merged: Record<string, EmbeddingIndexEntry>,\n ): Promise<EmbeddingIndexIdentity | null> {\n let identity: EmbeddingIndexIdentity | null = null;\n for (const name of await this.readShardNames()) {\n const read = await this.readFileAt(path.join(this.shardDir, name));\n if (read.outcome !== \"ok\") {\n if (read.outcome === \"unreadable\") {\n await this.recordIndexStatus({\n lastReadRecovery: { ts: new Date().toISOString(), message: `${name}: ${read.reason}` },\n });\n throw new EmbeddingIndexStorageError(\n `refusing to continue from unreadable embedding index shard ${name}: ${read.reason}`,\n );\n }\n await this.recordIndexStatus({\n lastReadRecovery: { ts: new Date().toISOString(), message: `${name}: unrecognized index format` },\n });\n throw new EmbeddingIndexStorageError(\n `refusing to continue from malformed embedding index shard ${name} (unrecognized format); file preserved in place`,\n );\n }\n try {\n validateShardMembership(name, read.file);\n } catch (error) {\n await this.recordIndexStatus({\n lastReadRecovery: { ts: new Date().toISOString(), message: String(error) },\n });\n throw error;\n }\n const shardIdentity = { provider: read.file.provider, model: read.file.model };\n if (!identity) identity = shardIdentity;\n if (!sameIndexIdentity(shardIdentity, identity)) {\n // A partial rewrite from this map would silently drop the foreign\n // shard's entries, so even recall must not serve this generation.\n throw new EmbeddingIndexStorageError(\n `refusing to continue from mixed-identity embedding index generation: ${name} is ${shardIdentity.provider}/${shardIdentity.model} but the generation identity is ${identity.provider}/${identity.model}; files preserved in place`,\n );\n }\n Object.assign(merged, read.file.entries);\n }\n return identity;\n }\n\n async readLegacy(): Promise<ManagedIndexRead> {\n return this.readFileAt(this.indexPath);\n }\n\n /**\n * Read one managed index file (legacy or shard). The file is never\n * modified or moved here: an unreadable file stays in place for recovery\n * and is reported through the returned outcome (mutation paths fail\n * closed on it; read-only paths fail open and record the reason).\n */\n /**\n * Read/mutation boundary for any generation member or the legacy marker\n * (codex PRRT_kwDORJXyws6mZ72r): a symlinked member is rejected outright\n * and its real target must stay inside the canonical state directory —\n * following a planted link would read or write outside the memory root.\n * Runs BEFORE the secure IO so storage-backed reads are covered too.\n */\n private async assertGenerationFileNotSymlinked(filePath: string): Promise<void> {\n const info = await lstat(filePath).catch((err) => {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw new EmbeddingIndexStorageError(\n `cannot lstat embedding index file ${filePath}: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n const stateDir = path.dirname(this.shardDir);\n // Containment must be checked even when the member itself is a regular\n // file: a SYMLINKED GENERATION DIRECTORY lets reads through to whatever\n // path the link resolves to — a regular file in a linked dir is still\n // outside the memory root and must be rejected.\n const real = await realpath(filePath).catch(() => null);\n if (real) {\n const scope = await realpath(stateDir).catch(() => stateDir);\n const rel = path.relative(scope, real);\n if (rel.startsWith(\"..\") || path.isAbsolute(rel)) {\n throw new EmbeddingIndexStorageError(\n `embedding index file escapes the state directory via symlink; refusing: ${filePath} -> ${real}`,\n );\n }\n }\n if (!info || !info.isSymbolicLink()) return;\n throw new EmbeddingIndexStorageError(\n `embedding index file is a symlink; refusing to read or write through it: ${filePath}`,\n );\n }\n\n async readFileAt(filePath: string): Promise<ManagedIndexRead> {\n await this.assertGenerationFileNotSymlinked(filePath);\n const hardLimit = resolveIndexHardReadCharLimit();\n let size = 0;\n try {\n size = (await stat(filePath)).size;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return { outcome: \"absent\" };\n return { outcome: \"unreadable\", reason: `stat failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n // Reads are gated by the HARD single-string ceiling only — NOT by the\n // soft write budget — so a legacy index from an older version sitting\n // between the two still loads and migrates (issue #3146). Byte size is\n // only a conservative bound for UTF-8 (bytes ≥ chars): at or below it a\n // readFile is guaranteed materializable; past it the file MAY still be\n // readable as a string, but refusing is the safe side. An over-ceiling\n // file is preserved in place; the caller decides fail-open (recall) or\n // fail-closed (mutation).\n if (size > hardLimit) {\n return {\n outcome: \"unreadable\",\n reason: `file is ${size} bytes, over the ${hardLimit}-char hard single-string read ceiling (V8 RangeError territory); bytes preserved in place — move or prune the file to recover`,\n };\n }\n let raw: string;\n try {\n raw = this.io\n ? await this.io.readUtf8(filePath)\n : await readFile(filePath, \"utf-8\");\n } catch (err) {\n return { outcome: \"unreadable\", reason: `read failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n return parseEmbeddingIndexDocument(raw);\n }\n\n private async readShardNames(): Promise<string[]> {\n try {\n return (await readdir(this.shardDir))\n .filter((name) => SHARD_FILE_PATTERN.test(name))\n .sort();\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return [];\n // The published generation exists but cannot be enumerated. Treating\n // it as empty would let a mutation overwrite shards it never saw, so\n // this must propagate — strict mutation fails closed, recall fails\n // open at its boundary (issue #3146 review).\n throw new EmbeddingIndexStorageError(\n `cannot enumerate embedding index shard directory ${this.shardDir}: ${err instanceof Error ? `${err.message} (${(err as NodeJS.ErrnoException).code ?? \"unknown\"})` : String(err)}`,\n );\n }\n }\n\n /**\n * Persist the index. Layout decisions, in order:\n * - published generation: rewrite only the shards this mutation touched;\n * - legacy/empty generation and the whole index fits one bounded JSON\n * string: stay the single `state/embeddings.json` file;\n * - over budget: ONE-WAY migration — stage a complete shard set, publish\n * it with a single directory rename, then rename the legacy file aside\n * as a non-authoritative recovery artifact (issue #3146).\n */\n async persist(\n index: EmbeddingIndexFile,\n opts: {\n touchedIds?: readonly string[];\n memoryId?: string;\n /** Reasserts mutation-lock ownership immediately before each destructive write (after serialization). */\n fence?: EmbeddingGenerationFence;\n } = {},\n ): Promise<void> {\n const stateDir = path.dirname(this.indexPath);\n await mkdir(stateDir, { recursive: true });\n await this.cleanForeignStagingDirs();\n // NOTE: interrupted-replacement recovery runs in the mutation wrapper\n // (EmbeddingFallback.enqueueIndexMutation) BEFORE this method, so the\n // caller's index already reflects the restored generation.\n\n const groups = shardEntriesForIndex(index);\n\n const layout = await this.detectLayout();\n\n if (layout === \"sharded\") {\n const limit = resolveIndexFileCharLimit();\n // An identity change on a published generation (a sharded host index\n // replaced by a fallback provider, or a host-model change) must\n // publish a COMPLETE replacement: the dirty-shard fast path would\n // rewrite only the touched shard under the new identity and leave the\n // former identity's shards in place — a mixed generation that every\n // later load rejects (codex P1, PR #3148).\n const diskIdentity = await this.identityFromDisk();\n if (groups.size === 0) {\n // An empty directory has no transport-visible deletion evidence.\n // Publish a valid empty shard so a peer without a shared base also\n // replaces its stale generation rather than preserving old vectors.\n groups.set(0, {});\n await this.publishReplacementGeneration(index, groups, limit, opts.fence);\n return;\n }\n const identityChanged =\n diskIdentity !== null &&\n (diskIdentity.provider !== index.provider || diskIdentity.model !== index.model);\n if (identityChanged) {\n await this.publishReplacementGeneration(index, groups, limit, opts.fence);\n return;\n }\n const dirtyShards = opts.touchedIds?.length\n ? new Set(opts.touchedIds.map((id) => shardIndexOf(id, SHARD_COUNT)))\n : null;\n // Serialize every touched shard BEFORE writing anything so a capacity\n // failure cannot leave a partial rewrite.\n const targets = dirtyShards ? [...dirtyShards] : [...groups.keys()];\n const payloads = targets\n .filter((shardIndex) => groups.has(shardIndex))\n .map((shardIndex) => ({\n shardIndex,\n body: serializeEmbeddingShard(index, shardIndex, groups.get(shardIndex)!, limit),\n }));\n // Serialization is done: reassert lock ownership immediately before\n // the destructive live-generation writes.\n await opts.fence?.();\n for (const payload of payloads) {\n await this.writeAtomicFile(\n path.join(this.shardDir, shardFileName(payload.shardIndex)),\n payload.body,\n );\n }\n // A dirty shard with no remaining entries (its last entry was just\n // removed) must be removed from disk, not silently skipped.\n for (const shardIndex of targets) {\n if (!groups.has(shardIndex)) {\n await rm(path.join(this.shardDir, shardFileName(shardIndex)), { force: true });\n }\n }\n return;\n }\n\n let whole: string | null;\n try {\n whole = JSON.stringify(index);\n } catch (err) {\n if (!isInvalidStringLengthError(err)) throw err;\n whole = null;\n }\n const limit = resolveIndexFileCharLimit();\n if (whole !== null && whole.length <= limit) {\n // Serialized above: reassert lock ownership immediately before the\n // destructive atomic write.\n await opts.fence?.();\n await this.writeAtomicFile(this.indexPath, whole);\n return;\n }\n\n // One-way migration. Until the publish rename, the legacy file stays\n // authoritative; afterwards the published directory is the only\n // generation and the legacy file is demoted to a recovery artifact.\n const stagingDir = path.join(\n stateDir,\n `embeddings.staging.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n );\n await mkdir(stagingDir, { recursive: true });\n try {\n await this.stageShardSet(stagingDir, index, groups, limit);\n // Atomic publish: the directory appearing IS the layout marker.\n await this.publishSwappedGeneration(stagingDir, opts.fence);\n } catch (err) {\n await rm(stagingDir, { recursive: true, force: true }).catch(() => undefined);\n throw err;\n }\n await rename(\n this.indexPath,\n `${this.indexPath}.pre-migration.tmp-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n ).catch(() => undefined);\n }\n\n /**\n * Replace a published generation wholesale after a provider/model identity\n * change (replacement semantics — the former entries are obsolete by\n * definition). Crash-safe by the same construction as the migration: the\n * COMPLETE new-identity set is staged and validated first (old bytes are\n * not touched until staging succeeds), then published atomically through\n * `publishSwappedGeneration`.\n */\n private async publishReplacementGeneration(\n index: EmbeddingIndexFile,\n groups: Map<number, Record<string, EmbeddingIndexEntry>>,\n limit: number,\n fence?: EmbeddingGenerationFence,\n ): Promise<void> {\n const stateDir = path.dirname(this.indexPath);\n const stagingDir = path.join(\n stateDir,\n `embeddings.staging.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`,\n );\n await mkdir(stagingDir, { recursive: true });\n try {\n await this.stageShardSet(stagingDir, index, groups, limit);\n await this.publishSwappedGeneration(stagingDir, fence);\n } catch (err) {\n await rm(stagingDir, { recursive: true, force: true }).catch(() => undefined);\n throw err;\n }\n }\n\n /**\n * Write a complete shard set into a staging directory. Every shard is\n * serialized before the first write, so a capacity failure cannot leave a\n * partial stage behind.\n */\n private async stageShardSet(\n stagingDir: string,\n index: EmbeddingIndexFile,\n groups: Map<number, Record<string, EmbeddingIndexEntry>>,\n limit: number,\n ): Promise<void> {\n const payloads = [...groups]\n .map(([shardIndex, entries]) => ({\n shardIndex,\n body: serializeEmbeddingShard(index, shardIndex, entries, limit),\n }));\n for (const payload of payloads) {\n const finalAadFilePath = path.join(this.shardDir, shardFileName(payload.shardIndex));\n await this.writeAtomicFile(\n path.join(stagingDir, shardFileName(payload.shardIndex)),\n payload.body,\n { finalAadFilePath },\n );\n }\n }\n\n /**\n * Atomically remove the published generation (offline-sync: the remote\n * deleted the whole index) by publishing an EMPTY staged directory\n * through the shared swap: the rename is atomic, so the former generation\n * moves whole into the fixed backup and back — a failure before the\n * commit rolls the former generation back intact, and a post-commit\n * backup-cleanup failure is non-fatal (the empty published directory\n * stays the authoritative one-way layout marker). The fixed backup is\n * symlink-checked first (round 5).\n */\n async removePublishedGeneration(fence?: EmbeddingGenerationFence): Promise<void> {\n const backupPath = replacementBackupPath(this.shardDir);\n await this.assertBackupNotSymlink(backupPath);\n await rm(backupPath, { recursive: true, force: true });\n // Remove by publishing an EMPTY staged directory through the SAME swap\n // state machine as every other publication: rename is atomic, so the\n // former generation moves whole into the fixed backup and back — a\n // partially-deleted generation can never be exposed. The empty\n // published directory stays the one-way layout marker, so a stray\n // legacy file can never become authoritative after removal. The\n // demoted backup's post-commit cleanup is non-fatal (existing\n // publishSwappedGeneration semantics).\n await mkdir(path.dirname(this.shardDir), { recursive: true });\n const emptyStaging = await mkdtemp(\n path.join(path.dirname(this.shardDir), \"embeddings.staging.tmp-empty-\"),\n );\n try {\n await this.publishSwappedGeneration(emptyStaging, fence);\n } catch (err) {\n await rm(emptyStaging, { recursive: true, force: true }).catch(() => undefined);\n throw err;\n }\n }\n\n /**\n * Atomically publish a fully staged generation directory as THE published\n * generation. The former published directory is demoted to the FIXED\n * transaction backup and the staging dir is renamed in with a single\n * rename; if the publish rename fails the former generation is rolled\n * back, and if the process dies in the rename gap `detectLayout()` /\n * `recoverIfInterrupted()` perform the same rollback on next use.\n * Shared by the mutation-side migration/replacement and the offline-sync\n * generation transaction (issue #3148, round 4) so there is exactly one\n * swap state machine. Staging-dir cleanup stays with the caller.\n */\n async publishSwappedGeneration(stagingDir: string, fence?: EmbeddingGenerationFence): Promise<void> {\n // The replacement is published: the backup is obsolete disk. A cleanup\n // failure is non-fatal (the next replacement removes it) but must stay\n // visible.\n const backupPath = replacementBackupPath(this.shardDir);\n await this.assertBackupNotSymlink(backupPath);\n // Cheap ownership check before the destructive backup cleanup: a peer\n // stale-break would otherwise see the backup vanish under it before we\n // even reach the live renames (Kilo PRRT_kwDORJXyws6mZ8i5).\n await fence?.();\n await rm(backupPath, { recursive: true, force: true });\n // Second ownership check immediately before the live renames: any\n // delay between the cleanup and the rename still allows a stale-break,\n // and publishing now would clobber the peer's write.\n await fence?.();\n let demoted = false;\n try {\n await stat(this.shardDir);\n await rename(this.shardDir, backupPath);\n demoted = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") throw err;\n }\n try {\n await rename(stagingDir, this.shardDir);\n } catch (err) {\n if (demoted) await rename(backupPath, this.shardDir).catch(() => undefined);\n throw err;\n }\n await rm(backupPath, { recursive: true, force: true }).catch((err) => {\n log.warn(`embedding index: could not remove replacement backup ${backupPath}: ${err}`);\n });\n }\n\n /** Remove staging dirs orphaned by crashed migrations. A foreign dir younger than the grace window may belong to a live writer mid-migration, so only older dirs are removed (issue #3148 review, round 3). */\n private static readonly STAGING_CLEANUP_GRACE_MS = 10 * 60 * 1000;\n\n private async cleanForeignStagingDirs(): Promise<void> {\n const stateDir = path.dirname(this.indexPath);\n let names: string[] = [];\n try {\n names = await readdir(stateDir);\n } catch {\n return;\n }\n const ownPrefix = `embeddings.staging.tmp-${process.pid}-`;\n const cutoff = Date.now() - EmbeddingIndexFileStore.STAGING_CLEANUP_GRACE_MS;\n for (const name of names) {\n if (!name.startsWith(\"embeddings.staging.tmp-\") || name.startsWith(ownPrefix)) continue;\n try {\n const stats = await stat(path.join(stateDir, name));\n if (stats.mtimeMs > cutoff) continue;\n } catch {\n continue;\n }\n await rm(path.join(stateDir, name), { recursive: true, force: true }).catch(() => undefined);\n }\n }\n\n /**\n * Temp-file + rename write. The temp name carries `.tmp-` so offline sync\n * ignores in-flight files under `state/`. With a wired io, the write goes\n * through the canonical secure-store contract instead, optionally binding\n * the ciphertext to the FINAL published path (staged shards).\n */\n private async writeAtomicFile(\n filePath: string,\n contents: string,\n opts?: { finalAadFilePath?: string; bypassSecureIo?: boolean },\n ): Promise<void> {\n if (this.io && opts?.bypassSecureIo !== true) {\n await this.io.writeUtf8(filePath, contents, opts?.finalAadFilePath === undefined ? undefined : { finalAadFilePath: opts.finalAadFilePath });\n return;\n }\n const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;\n try {\n await writeFile(tempPath, contents, \"utf-8\");\n await rename(tempPath, filePath);\n } catch (err) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw err;\n }\n }\n\n /**\n * Record the outcome of one index mutation durably. This is diagnostics,\n * NOT recovery: write failures are recorded and then re-thrown by the\n * caller so the extraction/consolidation task fails explicitly instead of\n * declaring success over an index that could not be persisted (issue\n * #3146).\n */\n async recordIndexWriteOutcome(err: unknown, memoryId?: string): Promise<void> {\n if (!err) {\n await this.recordIndexStatus({\n lastWriteFailure: null,\n lastSuccessAt: new Date().toISOString(),\n });\n return;\n }\n const kind: EmbeddingIndexWriteFailure[\"kind\"] =\n err instanceof EmbeddingIndexCapacityError || isInvalidStringLengthError(err)\n ? \"capacity\"\n : \"io\";\n await this.recordIndexStatus({\n failureCountIncrement: 1,\n lastWriteFailure: {\n ts: new Date().toISOString(),\n kind,\n message: err instanceof Error ? err.message : String(err),\n ...(memoryId ? { memoryId } : {}),\n },\n });\n }\n\n /**\n * Merge diagnostic state into `state/embedding-fallback-status.json`.\n * Best-effort: a diagnostics failure never masks the real outcome.\n */\n private async recordIndexStatus(\n patch: {\n failureCountIncrement?: number;\n lastWriteFailure?: EmbeddingIndexWriteFailure | null;\n lastReadRecovery?: { ts: string; message: string };\n lastSuccessAt?: string;\n },\n ): Promise<void> {\n try {\n let current: EmbeddingIndexStatusFile = { version: 1, failureCount: 0 };\n try {\n const parsed = JSON.parse(await readFile(this.statusPath, \"utf-8\")) as Partial<EmbeddingIndexStatusFile>;\n if (parsed && typeof parsed === \"object\" && typeof parsed.failureCount === \"number\") {\n current = { ...parsed, version: 1, failureCount: parsed.failureCount };\n }\n } catch {\n // Absent or unreadable status starts fresh; the index files own the truth.\n }\n const next: EmbeddingIndexStatusFile = { ...current };\n if (patch.failureCountIncrement) next.failureCount += patch.failureCountIncrement;\n if (patch.lastWriteFailure !== undefined) {\n if (patch.lastWriteFailure === null) delete next.lastWriteFailure;\n else next.lastWriteFailure = patch.lastWriteFailure;\n }\n if (patch.lastReadRecovery !== undefined) next.lastReadRecovery = patch.lastReadRecovery;\n if (patch.lastSuccessAt !== undefined) next.lastSuccessAt = patch.lastSuccessAt;\n // The status file is ALWAYS plain (non-secret diagnostics: failure\n // strings and counts only). It bypasses the secure io so console_state\n // keeps reading it on locked stores and failure counts never reset.\n await mkdir(path.dirname(this.statusPath), { recursive: true });\n await this.writeAtomicFile(this.statusPath, JSON.stringify(next), { bypassSecureIo: true });\n } catch (err) {\n log.debug(`embedding fallback status write failed: ${err}`);\n }\n }\n}\n\nfunction sameIndexIdentity(\n left: EmbeddingIndexIdentity,\n right: EmbeddingIndexIdentity,\n): boolean {\n return left.provider === right.provider && left.model === right.model;\n}\n"],"mappings":"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","names":["limit"]}