@remnic/core 9.52.2 → 9.54.0

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 (429) hide show
  1. package/dist/access-admin-ops-surface.d.ts +11 -11
  2. package/dist/access-admin-ops-surface.js +22 -22
  3. package/dist/access-authorization-probe.d.ts +11 -11
  4. package/dist/access-authorization-probe.js +23 -23
  5. package/dist/access-boundary.d.ts +11 -11
  6. package/dist/access-boundary.js +22 -22
  7. package/dist/access-cli.js +55 -55
  8. package/dist/access-coding-context-resolution.d.ts +1 -1
  9. package/dist/access-extraction-force-flush.d.ts +11 -11
  10. package/dist/access-extraction-force-flush.js +22 -22
  11. package/dist/access-health-types.d.ts +1 -1
  12. package/dist/access-http-lcm-compaction.d.ts +11 -11
  13. package/dist/access-http-lifecycle-flush.d.ts +11 -11
  14. package/dist/access-http-offline-stream.d.ts +11 -11
  15. package/dist/access-http-query.js +22 -22
  16. package/dist/access-http.d.ts +11 -11
  17. package/dist/access-http.js +29 -29
  18. package/dist/access-identity-continuity-surface.d.ts +9 -9
  19. package/dist/access-identity-continuity-surface.js +22 -22
  20. package/dist/access-lcm-surface.d.ts +11 -11
  21. package/dist/access-lcm-surface.js +22 -22
  22. package/dist/access-mcp.d.ts +11 -11
  23. package/dist/access-mcp.js +27 -27
  24. package/dist/access-memory-search-fanout.d.ts +2 -2
  25. package/dist/{access-namespace-preflight-Ds6CGlCP.d.ts → access-namespace-preflight-C7n4tgWC.d.ts} +1 -1
  26. package/dist/access-namespace-preflight.d.ts +3 -3
  27. package/dist/access-namespace-preflight.js +22 -22
  28. package/dist/access-observe-write-surface.d.ts +11 -11
  29. package/dist/access-observe-write-surface.js +22 -22
  30. package/dist/access-offline-manifest.d.ts +9 -9
  31. package/dist/access-offline-manifest.js +8 -4
  32. package/dist/access-operations-batch.js +24 -24
  33. package/dist/access-operations.d.ts +14 -14
  34. package/dist/access-operations.js +26 -26
  35. package/dist/access-recall-concurrency.d.ts +11 -11
  36. package/dist/access-recall-concurrency.js +22 -22
  37. package/dist/access-recall-response.d.ts +11 -11
  38. package/dist/access-recall-response.js +22 -22
  39. package/dist/access-recall-surface.d.ts +11 -11
  40. package/dist/access-recall-surface.js +22 -22
  41. package/dist/access-schema.d.ts +88 -88
  42. package/dist/{access-service-Cbk3bNbD.d.ts → access-service-CXvbxLK-.d.ts} +7 -7
  43. package/dist/access-service-helpers.d.ts +11 -11
  44. package/dist/access-service.d.ts +11 -11
  45. package/dist/access-service.js +22 -22
  46. package/dist/access-surface-catalog.d.ts +11 -11
  47. package/dist/access-wearables-meetings-surface.d.ts +3 -3
  48. package/dist/action-confidence.d.ts +1 -1
  49. package/dist/active-memory-bridge.d.ts +1 -1
  50. package/dist/active-recall.d.ts +1 -1
  51. package/dist/active-recall.js +5 -5
  52. package/dist/ambient-provenance.d.ts +1 -1
  53. package/dist/artifact-search.d.ts +1 -1
  54. package/dist/{auto-sync-QFQGOEO2.js → auto-sync-TDHLZPVP.js} +7 -7
  55. package/dist/behavior-learner.d.ts +1 -1
  56. package/dist/behavior-signals.d.ts +1 -1
  57. package/dist/bootstrap.d.ts +9 -9
  58. package/dist/briefing.d.ts +2 -2
  59. package/dist/briefing.js +12 -12
  60. package/dist/buffer-surprise-report.d.ts +1 -1
  61. package/dist/buffer-turn-helpers.d.ts +1 -1
  62. package/dist/buffer.d.ts +2 -2
  63. package/dist/bulk-import/index.d.ts +3 -3
  64. package/dist/calibration.d.ts +1 -1
  65. package/dist/capabilities.d.ts +1 -1
  66. package/dist/{catalog-D3B4RDy1.d.ts → catalog-BOOxl-I2.d.ts} +1 -1
  67. package/dist/causal-behavior.d.ts +1 -1
  68. package/dist/causal-consolidation.d.ts +1 -1
  69. package/dist/causal-consolidation.js +13 -13
  70. package/dist/causal-trajectory-graph.d.ts +1 -1
  71. package/dist/{chunk-MLXZD4WM.js → chunk-2GFK22OZ.js} +2 -2
  72. package/dist/{chunk-RANKJI5T.js → chunk-3JLPGJ43.js} +2 -2
  73. package/dist/{chunk-O5FFBO2M.js → chunk-47P3RYZP.js} +70 -8
  74. package/dist/{chunk-O5FFBO2M.js.map → chunk-47P3RYZP.js.map} +1 -1
  75. package/dist/{chunk-X7XEDOSL.js → chunk-4IIFL7GC.js} +8 -8
  76. package/dist/chunk-5FVVY2EB.js +27 -0
  77. package/dist/chunk-5FVVY2EB.js.map +1 -0
  78. package/dist/{chunk-GXSOUIA4.js → chunk-5WQMORU5.js} +4 -4
  79. package/dist/{chunk-J272WKX2.js → chunk-6HPHEFXT.js} +2 -2
  80. package/dist/{chunk-B6LZ4IBH.js → chunk-6LAPLZOS.js} +2 -2
  81. package/dist/{chunk-WD5B5AIE.js → chunk-6R4G7N4S.js} +118 -173
  82. package/dist/chunk-6R4G7N4S.js.map +1 -0
  83. package/dist/{chunk-VXCNQYTC.js → chunk-APPFNGX6.js} +2 -2
  84. package/dist/{chunk-GXFSQ6SD.js → chunk-C4ZNGVK3.js} +2 -2
  85. package/dist/{chunk-JSEJH2YQ.js → chunk-CGVHPCP2.js} +2 -2
  86. package/dist/{chunk-BQIFZ2MP.js → chunk-CX5SW2EW.js} +41 -24
  87. package/dist/chunk-CX5SW2EW.js.map +1 -0
  88. package/dist/{chunk-RMHMUUBW.js → chunk-CYF6WVE7.js} +105 -49
  89. package/dist/{chunk-RMHMUUBW.js.map → chunk-CYF6WVE7.js.map} +1 -1
  90. package/dist/{chunk-TEMSWHQD.js → chunk-DZD576ZU.js} +5 -5
  91. package/dist/{chunk-AMTEYNYK.js → chunk-EVWWT3KE.js} +4 -4
  92. package/dist/{chunk-P2KBDJJ6.js → chunk-G2LUMAUF.js} +4 -3
  93. package/dist/{chunk-P2KBDJJ6.js.map → chunk-G2LUMAUF.js.map} +1 -1
  94. package/dist/{chunk-AXIDQG5A.js → chunk-G4T7L557.js} +5 -5
  95. package/dist/{chunk-7M6NYQWB.js → chunk-G7Z6EENO.js} +4 -4
  96. package/dist/{chunk-IARXXZU4.js → chunk-HOIRB77A.js} +99 -20
  97. package/dist/chunk-HOIRB77A.js.map +1 -0
  98. package/dist/{chunk-NDAH7BJ5.js → chunk-HVP33QVW.js} +103 -6
  99. package/dist/chunk-HVP33QVW.js.map +1 -0
  100. package/dist/{chunk-YXKVLYXU.js → chunk-HWRD23DW.js} +2 -2
  101. package/dist/{chunk-SOEN6KCF.js → chunk-IBKR2TFR.js} +2 -2
  102. package/dist/{chunk-R3DJVOSM.js → chunk-JDSVLVCG.js} +8 -1
  103. package/dist/chunk-JDSVLVCG.js.map +1 -0
  104. package/dist/{chunk-F4EU6VUC.js → chunk-JDZPNCMA.js} +2 -2
  105. package/dist/{chunk-D5YOZ66N.js → chunk-JV5YUBIZ.js} +20 -20
  106. package/dist/{chunk-DLG5V6ND.js → chunk-K4QS7LXU.js} +4 -7
  107. package/dist/chunk-K4QS7LXU.js.map +1 -0
  108. package/dist/{chunk-BAKXNQ3C.js → chunk-KRTY3ENI.js} +2 -2
  109. package/dist/{chunk-NK5RGJ65.js → chunk-L4DLLKPN.js} +2 -2
  110. package/dist/{chunk-VFSAWRMZ.js → chunk-LJS7KUPV.js} +2 -2
  111. package/dist/{chunk-JJRVPWFY.js → chunk-MLPTFODV.js} +166 -37
  112. package/dist/chunk-MLPTFODV.js.map +1 -0
  113. package/dist/{chunk-NOEMGE56.js → chunk-NH5IR2WM.js} +2 -2
  114. package/dist/{chunk-5V6IXHPI.js → chunk-NSVDUN76.js} +2 -2
  115. package/dist/{chunk-W7Y5JDVB.js → chunk-PDDTI7IC.js} +4 -4
  116. package/dist/{chunk-QINJITDS.js → chunk-PX2LSHYM.js} +2 -2
  117. package/dist/{chunk-HDIUYMSB.js → chunk-QWGE2PUH.js} +6 -6
  118. package/dist/{chunk-X57M2Q4I.js → chunk-RDJRFDJY.js} +3 -3
  119. package/dist/{chunk-RYLEDKQ2.js → chunk-RUMNY5DT.js} +3 -3
  120. package/dist/{chunk-BKIFTXHR.js → chunk-RZ4XGKOJ.js} +2 -2
  121. package/dist/{chunk-66SE3BNH.js → chunk-SUPEYLH2.js} +2 -2
  122. package/dist/{chunk-BF6SXNQJ.js → chunk-T2JHZWH6.js} +20 -20
  123. package/dist/{chunk-VHFXP27N.js → chunk-THPPCISA.js} +60 -23
  124. package/dist/chunk-THPPCISA.js.map +1 -0
  125. package/dist/{chunk-QPOHMO6M.js → chunk-UES4BHA2.js} +2 -2
  126. package/dist/{chunk-XAPMEU3K.js → chunk-UU7TRFNE.js} +2 -2
  127. package/dist/{chunk-QBSFOKY6.js → chunk-VOELBUS4.js} +4 -4
  128. package/dist/{chunk-2LY6GIIE.js → chunk-WDBX6VER.js} +2 -2
  129. package/dist/{chunk-BMEYMKWX.js → chunk-WM65LU67.js} +2 -2
  130. package/dist/{chunk-WLRD2TXF.js → chunk-WOPA3SGI.js} +4 -4
  131. package/dist/{chunk-5UZ6UCOZ.js → chunk-XUAMCLY4.js} +3 -3
  132. package/dist/{chunk-7HXZJAID.js → chunk-YGLY6QFV.js} +3 -3
  133. package/dist/{chunk-2OIQDTDC.js → chunk-ZPJ4QSGP.js} +2 -2
  134. package/dist/{chunk-3OY7KXHM.js → chunk-ZYLC7NFO.js} +3 -3
  135. package/dist/{cli-DMAFI0qt.d.ts → cli-DVUFIa5E.d.ts} +5 -5
  136. package/dist/cli.d.ts +13 -13
  137. package/dist/cli.js +42 -42
  138. package/dist/coding/pre-action-gate.d.ts +1 -1
  139. package/dist/compounding/engine.d.ts +2 -2
  140. package/dist/compounding/engine.js +13 -13
  141. package/dist/compounding/preference-consolidator.d.ts +1 -1
  142. package/dist/compression-optimizer.d.ts +1 -1
  143. package/dist/config.d.ts +1 -1
  144. package/dist/config.js +5 -5
  145. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  146. package/dist/connectors/codex-materialize-runner.js +12 -12
  147. package/dist/connectors/codex-materialize.d.ts +1 -1
  148. package/dist/connectors/index.d.ts +1 -1
  149. package/dist/connectors/index.js +12 -12
  150. package/dist/consolidation-provenance-check.d.ts +2 -2
  151. package/dist/consolidation-undo.d.ts +2 -2
  152. package/dist/content-hash.d.ts +12 -2
  153. package/dist/content-hash.js +9 -3
  154. package/dist/contradiction/index.d.ts +2 -2
  155. package/dist/contradiction/index.js +3 -3
  156. package/dist/converge-config.d.ts +1 -1
  157. package/dist/convergence-refresh.d.ts +2 -2
  158. package/dist/convergence-refresh.js +14 -14
  159. package/dist/conversation-index/backend.d.ts +1 -1
  160. package/dist/conversation-index/chunker.d.ts +1 -1
  161. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  162. package/dist/conversation-index/indexer.d.ts +1 -1
  163. package/dist/conversation-index/search.d.ts +1 -1
  164. package/dist/corpus-watermark.d.ts +1 -1
  165. package/dist/corpus-watermark.js +14 -14
  166. package/dist/day-summary.d.ts +1 -1
  167. package/dist/delinearize.d.ts +1 -1
  168. package/dist/dependency-propagation-config.d.ts +1 -1
  169. package/dist/{dependency-propagation-delivery-D63r24pH.d.ts → dependency-propagation-delivery-XzF76C9n.d.ts} +1 -1
  170. package/dist/direct-answer-wiring.d.ts +1 -1
  171. package/dist/direct-answer.d.ts +1 -1
  172. package/dist/embedding-fallback.d.ts +1 -1
  173. package/dist/enrichment/index.d.ts +1 -1
  174. package/dist/entity-retrieval.d.ts +2 -2
  175. package/dist/entity-retrieval.js +12 -12
  176. package/dist/entity-schema.d.ts +1 -1
  177. package/dist/explicit-capture.d.ts +9 -9
  178. package/dist/explicit-capture.js +8 -8
  179. package/dist/external-wiki-access.d.ts +11 -11
  180. package/dist/external-wiki-access.js +23 -23
  181. package/dist/external-wiki-collection-registration.d.ts +1 -1
  182. package/dist/external-wiki-collection.d.ts +1 -1
  183. package/dist/external-wiki-mcp-tools.d.ts +11 -11
  184. package/dist/extraction-error-classification.d.ts +1 -1
  185. package/dist/extraction-faithfulness.d.ts +1 -1
  186. package/dist/extraction-judge-telemetry.d.ts +1 -1
  187. package/dist/extraction-judge-training.d.ts +1 -1
  188. package/dist/extraction-judge.d.ts +1 -1
  189. package/dist/extraction-liveness.d.ts +1 -1
  190. package/dist/extraction-normalization.d.ts +1 -1
  191. package/dist/extraction-normalization.js +2 -2
  192. package/dist/extraction-prompt.d.ts +1 -1
  193. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  194. package/dist/extraction-source-grounding.d.ts +1 -1
  195. package/dist/extraction-source-grounding.js +3 -3
  196. package/dist/extraction.d.ts +1 -1
  197. package/dist/extraction.js +16 -16
  198. package/dist/fallback-llm.d.ts +1 -1
  199. package/dist/{forget-HDS4N6CG.js → forget-EHGGJZLX.js} +3 -2
  200. package/dist/{forget-HDS4N6CG.js.map → forget-EHGGJZLX.js.map} +1 -1
  201. package/dist/graph-dashboard-diff.d.ts +1 -1
  202. package/dist/graph-dashboard-key.d.ts +1 -1
  203. package/dist/graph-dashboard-parser.d.ts +1 -1
  204. package/dist/graph-edge-reinforcement.d.ts +1 -1
  205. package/dist/graph-path-reconstruction.d.ts +1 -1
  206. package/dist/graph-path-scoring.d.ts +1 -1
  207. package/dist/graph-snapshot.d.ts +1 -1
  208. package/dist/graph.d.ts +1 -1
  209. package/dist/harmonic-construction.js +2 -2
  210. package/dist/harmonic-retrieval.js +4 -4
  211. package/dist/importance.d.ts +1 -1
  212. package/dist/importers/index.d.ts +1 -1
  213. package/dist/in-flight-reads.d.ts +1 -1
  214. package/dist/index.d.ts +777 -705
  215. package/dist/index.js +77 -67
  216. package/dist/intent.d.ts +1 -1
  217. package/dist/lcm/engine.d.ts +1 -1
  218. package/dist/lcm/index.d.ts +1 -1
  219. package/dist/lcm/tools.d.ts +1 -1
  220. package/dist/lifecycle.d.ts +1 -1
  221. package/dist/live-connectors-runner.d.ts +1 -1
  222. package/dist/local-llm.d.ts +1 -1
  223. package/dist/local-model-endpoint.d.ts +1 -1
  224. package/dist/maintenance/memory-governance.d.ts +1 -1
  225. package/dist/maintenance/memory-governance.js +12 -12
  226. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  227. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -12
  228. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  229. package/dist/maintenance/rebuild-memory-projection.js +13 -13
  230. package/dist/{maintenance-kBII2qUI.d.ts → maintenance-BJzNIKBE.d.ts} +3 -3
  231. package/dist/mcp-memory-inspector-app.d.ts +11 -11
  232. package/dist/memory-action-policy.d.ts +1 -1
  233. package/dist/memory-cache.d.ts +1 -1
  234. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  235. package/dist/memory-projection-store.d.ts +1 -1
  236. package/dist/memory-provenance.d.ts +1 -1
  237. package/dist/memory-snapshot.d.ts +1 -1
  238. package/dist/memory-worth-outcomes.d.ts +2 -2
  239. package/dist/models-json.d.ts +1 -1
  240. package/dist/namespaces/migrate.d.ts +3 -3
  241. package/dist/namespaces/migrate.js +13 -13
  242. package/dist/namespaces/principal.d.ts +1 -1
  243. package/dist/namespaces/search.d.ts +1 -1
  244. package/dist/namespaces/storage.d.ts +3 -3
  245. package/dist/namespaces/storage.js +12 -12
  246. package/dist/native-knowledge.d.ts +1 -1
  247. package/dist/offline-sync-impression-drain.d.ts +1 -1
  248. package/dist/operator-doctor-corpus.d.ts +1 -1
  249. package/dist/operator-doctor-corpus.js +15 -15
  250. package/dist/operator-doctor-replica.d.ts +1 -1
  251. package/dist/operator-toolkit.d.ts +3 -3
  252. package/dist/operator-toolkit.js +21 -21
  253. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  254. package/dist/orchestration/maintenance.d.ts +4 -4
  255. package/dist/orchestration/maintenance.js +17 -17
  256. package/dist/{orchestrator-DHy5LtTy.d.ts → orchestrator-BiXgBJBQ.d.ts} +8 -8
  257. package/dist/orchestrator.d.ts +9 -9
  258. package/dist/orchestrator.js +55 -55
  259. package/dist/patterns-cli.d.ts +1 -1
  260. package/dist/{pipeline-D21Rs6gW.d.ts → pipeline-sz_dcuLg.d.ts} +1 -1
  261. package/dist/policy-runtime.d.ts +1 -1
  262. package/dist/proactive-contention.d.ts +1 -1
  263. package/dist/provenance.d.ts +1 -1
  264. package/dist/provenance.js +2 -2
  265. package/dist/{qmd-Dhle1P4X.d.ts → qmd-eAWObK4M.d.ts} +1 -1
  266. package/dist/qmd-preflight.d.ts +2 -2
  267. package/dist/qmd-recall-cache.d.ts +1 -1
  268. package/dist/qmd.d.ts +2 -2
  269. package/dist/recall-concurrency-config.d.ts +1 -1
  270. package/dist/recall-disclosure-escalation.d.ts +1 -1
  271. package/dist/recall-explain-renderer.d.ts +1 -1
  272. package/dist/recall-memory-map.d.ts +1 -1
  273. package/dist/recall-planner-llm.d.ts +1 -1
  274. package/dist/recall-state.d.ts +1 -1
  275. package/dist/recall-tag-filter.d.ts +1 -1
  276. package/dist/recall-timings.d.ts +1 -1
  277. package/dist/recall-xray-cli.d.ts +1 -1
  278. package/dist/recall-xray-renderer.d.ts +1 -1
  279. package/dist/recall-xray.d.ts +1 -1
  280. package/dist/reconcile/cursor.d.ts +1 -1
  281. package/dist/reconcile/manifest.d.ts +4 -2
  282. package/dist/reconcile/manifest.js +7 -3
  283. package/dist/reconcile/plan.d.ts +1 -1
  284. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  285. package/dist/replay/normalizers/claude.d.ts +1 -1
  286. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  287. package/dist/replay/normalizers/shared.d.ts +1 -1
  288. package/dist/replay/runner.d.ts +1 -1
  289. package/dist/replay/types.d.ts +1 -1
  290. package/dist/replica-divergence.d.ts +1 -1
  291. package/dist/replica-peers-config.d.ts +1 -1
  292. package/dist/{resolution-MDPNOEG6.js → resolution-MMOD5WC4.js} +4 -4
  293. package/dist/resolve-auth-token.d.ts +1 -1
  294. package/dist/resume-bundles.js +6 -6
  295. package/dist/retrieval-agents.d.ts +2 -2
  296. package/dist/retrieval-tiers.d.ts +1 -1
  297. package/dist/routing/engine.d.ts +1 -1
  298. package/dist/routing/store.d.ts +1 -1
  299. package/dist/salvage-envelope.d.ts +1 -1
  300. package/dist/salvage-envelope.js +3 -3
  301. package/dist/schemas.d.ts +138 -138
  302. package/dist/{scope-profiles-NzGPDXLn.d.ts → scope-profiles-BBQsXuyj.d.ts} +1 -1
  303. package/dist/search/embed-helper.d.ts +1 -1
  304. package/dist/search/factory.d.ts +1 -1
  305. package/dist/search/index.d.ts +1 -1
  306. package/dist/search/lancedb-backend.d.ts +1 -1
  307. package/dist/search/meilisearch-backend.d.ts +1 -1
  308. package/dist/search/noop-backend.d.ts +1 -1
  309. package/dist/search/orama-backend.d.ts +1 -1
  310. package/dist/search/port.d.ts +1 -1
  311. package/dist/search/remote-backend.d.ts +1 -1
  312. package/dist/{semantic-consolidation-DLDKvyy5.d.ts → semantic-consolidation-HD8RkzVA.d.ts} +1 -1
  313. package/dist/semantic-consolidation.d.ts +2 -2
  314. package/dist/semantic-consolidation.js +13 -13
  315. package/dist/semantic-rule-promotion.js +12 -12
  316. package/dist/semantic-rule-verifier.d.ts +1 -1
  317. package/dist/semantic-rule-verifier.js +12 -12
  318. package/dist/{service-PT2_z7xm.d.ts → service-DIrtHHEg.d.ts} +2 -2
  319. package/dist/session-observer-bands.d.ts +1 -1
  320. package/dist/session-observer-state.d.ts +1 -1
  321. package/dist/shared-context/manager.d.ts +9 -9
  322. package/dist/signal.d.ts +1 -1
  323. package/dist/source-agent-qualifier.d.ts +1 -1
  324. package/dist/source-agent-qualifier.js +14 -14
  325. package/dist/{storage-BmVudhk4.d.ts → storage-DqCzXi56.d.ts} +37 -33
  326. package/dist/storage.d.ts +2 -2
  327. package/dist/storage.js +14 -14
  328. package/dist/structured-attributes.d.ts +3 -1
  329. package/dist/structured-attributes.js +3 -1
  330. package/dist/summarizer.d.ts +1 -1
  331. package/dist/summary-snapshot.d.ts +1 -1
  332. package/dist/temporal-supersession.d.ts +2 -2
  333. package/dist/temporal-timeline-recall.d.ts +1 -1
  334. package/dist/temporal-validity.d.ts +1 -1
  335. package/dist/threading.d.ts +1 -1
  336. package/dist/tier-migration.d.ts +2 -2
  337. package/dist/tier-routing.d.ts +1 -1
  338. package/dist/topics.d.ts +1 -1
  339. package/dist/transcript.d.ts +1 -1
  340. package/dist/transfer/types.d.ts +66 -66
  341. package/dist/trust-score-stage.d.ts +1 -1
  342. package/dist/trust-score.d.ts +1 -1
  343. package/dist/{types-CkiDUorT.d.ts → types-d_j4vC6N.d.ts} +26 -1
  344. package/dist/types.d.ts +1 -1
  345. package/dist/utility-runtime.d.ts +1 -1
  346. package/dist/verified-recall.js +12 -12
  347. package/dist/write-envelope.d.ts +1 -1
  348. package/dist/write-envelope.js +2 -2
  349. package/package.json +2 -2
  350. package/src/access-offline-manifest.ts +1 -0
  351. package/src/access-service-offline-file-content.test.ts +1 -0
  352. package/src/content-hash.ts +34 -1
  353. package/src/dedup/index.test.ts +56 -38
  354. package/src/dedup/index.ts +85 -38
  355. package/src/lifecycle/tombstones.test.ts +763 -16
  356. package/src/lifecycle/tombstones.ts +217 -50
  357. package/src/reconcile/manifest.test.ts +158 -1
  358. package/src/reconcile/manifest.ts +76 -22
  359. package/src/storage/content-hash-index.ts +56 -40
  360. package/src/storage/entity-ref-repair.ts +3 -3
  361. package/src/storage/memory-read-store.ts +9 -0
  362. package/src/storage/tombstone-blocked-capture-index.ts +4 -9
  363. package/src/storage-contract/content-hash.test.ts +13 -0
  364. package/src/storage-fact-hash-index-defer.test.ts +1 -1
  365. package/src/storage.ts +107 -93
  366. package/src/structured-attributes.ts +11 -0
  367. package/src/wearables/cleanup.test.ts +71 -0
  368. package/src/wearables/cleanup.ts +163 -16
  369. package/src/wearables/config.test.ts +62 -0
  370. package/src/wearables/config.ts +99 -5
  371. package/src/wearables/index.ts +10 -0
  372. package/src/wearables/pipeline.test.ts +36 -0
  373. package/src/wearables/pipeline.ts +18 -3
  374. package/src/wearables/redaction.test.ts +156 -0
  375. package/src/wearables/redaction.ts +102 -10
  376. package/src/wearables/text-language.ts +146 -0
  377. package/src/wearables/types.ts +26 -0
  378. package/dist/chunk-BQIFZ2MP.js.map +0 -1
  379. package/dist/chunk-DLG5V6ND.js.map +0 -1
  380. package/dist/chunk-IARXXZU4.js.map +0 -1
  381. package/dist/chunk-JJRVPWFY.js.map +0 -1
  382. package/dist/chunk-NDAH7BJ5.js.map +0 -1
  383. package/dist/chunk-R3DJVOSM.js.map +0 -1
  384. package/dist/chunk-VHFXP27N.js.map +0 -1
  385. package/dist/chunk-W5H6ZRPT.js +0 -14
  386. package/dist/chunk-W5H6ZRPT.js.map +0 -1
  387. package/dist/chunk-WD5B5AIE.js.map +0 -1
  388. /package/dist/{auto-sync-QFQGOEO2.js.map → auto-sync-TDHLZPVP.js.map} +0 -0
  389. /package/dist/{chunk-MLXZD4WM.js.map → chunk-2GFK22OZ.js.map} +0 -0
  390. /package/dist/{chunk-RANKJI5T.js.map → chunk-3JLPGJ43.js.map} +0 -0
  391. /package/dist/{chunk-X7XEDOSL.js.map → chunk-4IIFL7GC.js.map} +0 -0
  392. /package/dist/{chunk-GXSOUIA4.js.map → chunk-5WQMORU5.js.map} +0 -0
  393. /package/dist/{chunk-J272WKX2.js.map → chunk-6HPHEFXT.js.map} +0 -0
  394. /package/dist/{chunk-B6LZ4IBH.js.map → chunk-6LAPLZOS.js.map} +0 -0
  395. /package/dist/{chunk-VXCNQYTC.js.map → chunk-APPFNGX6.js.map} +0 -0
  396. /package/dist/{chunk-GXFSQ6SD.js.map → chunk-C4ZNGVK3.js.map} +0 -0
  397. /package/dist/{chunk-JSEJH2YQ.js.map → chunk-CGVHPCP2.js.map} +0 -0
  398. /package/dist/{chunk-TEMSWHQD.js.map → chunk-DZD576ZU.js.map} +0 -0
  399. /package/dist/{chunk-AMTEYNYK.js.map → chunk-EVWWT3KE.js.map} +0 -0
  400. /package/dist/{chunk-AXIDQG5A.js.map → chunk-G4T7L557.js.map} +0 -0
  401. /package/dist/{chunk-7M6NYQWB.js.map → chunk-G7Z6EENO.js.map} +0 -0
  402. /package/dist/{chunk-YXKVLYXU.js.map → chunk-HWRD23DW.js.map} +0 -0
  403. /package/dist/{chunk-SOEN6KCF.js.map → chunk-IBKR2TFR.js.map} +0 -0
  404. /package/dist/{chunk-F4EU6VUC.js.map → chunk-JDZPNCMA.js.map} +0 -0
  405. /package/dist/{chunk-D5YOZ66N.js.map → chunk-JV5YUBIZ.js.map} +0 -0
  406. /package/dist/{chunk-BAKXNQ3C.js.map → chunk-KRTY3ENI.js.map} +0 -0
  407. /package/dist/{chunk-NK5RGJ65.js.map → chunk-L4DLLKPN.js.map} +0 -0
  408. /package/dist/{chunk-VFSAWRMZ.js.map → chunk-LJS7KUPV.js.map} +0 -0
  409. /package/dist/{chunk-NOEMGE56.js.map → chunk-NH5IR2WM.js.map} +0 -0
  410. /package/dist/{chunk-5V6IXHPI.js.map → chunk-NSVDUN76.js.map} +0 -0
  411. /package/dist/{chunk-W7Y5JDVB.js.map → chunk-PDDTI7IC.js.map} +0 -0
  412. /package/dist/{chunk-QINJITDS.js.map → chunk-PX2LSHYM.js.map} +0 -0
  413. /package/dist/{chunk-HDIUYMSB.js.map → chunk-QWGE2PUH.js.map} +0 -0
  414. /package/dist/{chunk-X57M2Q4I.js.map → chunk-RDJRFDJY.js.map} +0 -0
  415. /package/dist/{chunk-RYLEDKQ2.js.map → chunk-RUMNY5DT.js.map} +0 -0
  416. /package/dist/{chunk-BKIFTXHR.js.map → chunk-RZ4XGKOJ.js.map} +0 -0
  417. /package/dist/{chunk-66SE3BNH.js.map → chunk-SUPEYLH2.js.map} +0 -0
  418. /package/dist/{chunk-BF6SXNQJ.js.map → chunk-T2JHZWH6.js.map} +0 -0
  419. /package/dist/{chunk-QPOHMO6M.js.map → chunk-UES4BHA2.js.map} +0 -0
  420. /package/dist/{chunk-XAPMEU3K.js.map → chunk-UU7TRFNE.js.map} +0 -0
  421. /package/dist/{chunk-QBSFOKY6.js.map → chunk-VOELBUS4.js.map} +0 -0
  422. /package/dist/{chunk-2LY6GIIE.js.map → chunk-WDBX6VER.js.map} +0 -0
  423. /package/dist/{chunk-BMEYMKWX.js.map → chunk-WM65LU67.js.map} +0 -0
  424. /package/dist/{chunk-WLRD2TXF.js.map → chunk-WOPA3SGI.js.map} +0 -0
  425. /package/dist/{chunk-5UZ6UCOZ.js.map → chunk-XUAMCLY4.js.map} +0 -0
  426. /package/dist/{chunk-7HXZJAID.js.map → chunk-YGLY6QFV.js.map} +0 -0
  427. /package/dist/{chunk-2OIQDTDC.js.map → chunk-ZPJ4QSGP.js.map} +0 -0
  428. /package/dist/{chunk-3OY7KXHM.js.map → chunk-ZYLC7NFO.js.map} +0 -0
  429. /package/dist/{resolution-MDPNOEG6.js.map → resolution-MMOD5WC4.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/storage/tombstone-blocked-capture-mutation.ts","../src/storage/tombstone-blocked-capture-sync.ts","../src/storage/tombstone-blocked-capture-index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { withHeldFileLock } from \"../utils/serialize-mutations.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nconst TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS = 60_000;\nconst CAPTURE_WRITE_LOCK_MAX_ATTEMPTS = 3;\nconst CAPTURE_WRITE_LOCK_RETRY_BASE_MS = 25;\nconst CAPTURE_WRITE_LOCK_BUSY_MESSAGE = \"tombstone-blocked capture write lock remained busy\";\n\nexport function isTombstoneBlockedCaptureWriteLockBusy(error: unknown): boolean {\n return error instanceof Error && error.message === CAPTURE_WRITE_LOCK_BUSY_MESSAGE;\n}\n\nexport function normalizeExplicitCaptureContent(value: string): string {\n return value.toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\nexport function buildExplicitCaptureDedupKey(\n content: string,\n category: string,\n sourceConnector: string | undefined\n): string {\n const encode = (label: string, value: string): string => `${label} ${value.length} ${value}`;\n return [\n encode(\"category\", category),\n encode(\"connector\", sourceConnector?.trim() ?? \"\"),\n encode(\"content\", normalizeExplicitCaptureContent(content)),\n ].join(\" \");\n}\n\nexport function buildCapturePathLockIdentity(pathname: string): string {\n return `path ${pathname.length} ${pathname}`;\n}\n\nexport function captureIdentityHash(memory: MemoryFile): string {\n return createHash(\"sha256\")\n .update(\n buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)\n )\n .digest(\"hex\");\n}\n\nexport type TombstoneBlockedCaptureWriteLockOptions = {\n readonly stateDir: string;\n readonly withHeldFileLock?: typeof withHeldFileLock;\n};\n\nexport class TombstoneBlockedCaptureWriteLock {\n private readonly context = new AsyncLocalStorage<ReadonlySet<string>>();\n\n constructor(private readonly options: TombstoneBlockedCaptureWriteLockOptions) {}\n\n private captureWriteLockPathForHash(identityHash: string): string {\n const filename =\n identityHash.length === 0 ? \"explicit-capture-write.lock\" : `explicit-capture-write-${identityHash}.lock`;\n return path.join(this.options.stateDir, \"tombstone-blocked-capture\", filename);\n }\n\n private async withSingleCaptureWriteLock<T>(lockPath: string, task: () => Promise<T>): Promise<T> {\n await mkdir(path.dirname(lockPath), { recursive: true });\n const retry = Symbol(\"retry\");\n const permanentFailure = Symbol(\"permanent-failure\");\n const runWithHeldFileLock = this.options.withHeldFileLock ?? withHeldFileLock;\n for (let attempt = 0; attempt < CAPTURE_WRITE_LOCK_MAX_ATTEMPTS; attempt += 1) {\n const result = await runWithHeldFileLock<T | typeof retry | typeof permanentFailure>(\n lockPath,\n {\n staleMs: TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS,\n maxWaitMs: 1_000,\n pollMs: 25,\n },\n async (acquired, controller) => {\n if (acquired) return await task();\n return controller.failure === \"error\" ? permanentFailure : retry;\n }\n );\n if (result === permanentFailure) {\n throw new Error(\"tombstone-blocked capture write lock acquisition failed\");\n }\n if (result !== retry) return result;\n if (attempt === CAPTURE_WRITE_LOCK_MAX_ATTEMPTS - 1) break;\n const delayState = Promise.withResolvers<void>();\n setTimeout(delayState.resolve, CAPTURE_WRITE_LOCK_RETRY_BASE_MS * 2 ** attempt);\n await delayState.promise;\n }\n throw new Error(CAPTURE_WRITE_LOCK_BUSY_MESSAGE);\n }\n private async withPhysicalCaptureWriteLocks<T>(\n task: () => Promise<T>,\n identityHashes: readonly string[]\n ): Promise<T> {\n const lockPaths = [...new Set(identityHashes.map((hash) => this.captureWriteLockPathForHash(hash)))];\n const acquire = async (index: number): Promise<T> => {\n if (index === lockPaths.length) return await task();\n return await this.withSingleCaptureWriteLock(lockPaths[index], () => acquire(index + 1));\n };\n return await acquire(0);\n }\n\n async withCaptureWriteLock<T>(task: () => Promise<T>, identity?: string | readonly string[]): Promise<T> {\n const identities =\n Array.isArray(identity) && identity.length > 0 ? identity : [typeof identity === \"string\" ? identity : \"\"];\n return await this.withCaptureWriteLocks(task, identities, []);\n }\n\n async withCaptureWriteLockHashes<T>(task: () => Promise<T>, identityHashes: readonly string[]): Promise<T> {\n return await this.withCaptureWriteLocks(task, [], identityHashes);\n }\n\n async withCaptureWriteLockAndHashes<T>(\n task: () => Promise<T>,\n identity: string | readonly string[] | undefined,\n identityHashes: readonly string[]\n ): Promise<T> {\n const identities =\n Array.isArray(identity) && identity.length > 0 ? identity : [typeof identity === \"string\" ? identity : \"\"];\n return await this.withCaptureWriteLocks(task, identities, identityHashes);\n }\n\n private async withCaptureWriteLocks<T>(\n task: () => Promise<T>,\n identities: readonly string[],\n identityHashes: readonly string[]\n ): Promise<T> {\n const current = this.context.getStore();\n const hashToken = (key: string): string =>\n `\\u0000${key.length === 0 ? \"\" : createHash(\"sha256\").update(key).digest(\"hex\")}`;\n const identityHash = (key: string): string =>\n key.length === 0 ? \"\" : createHash(\"sha256\").update(key).digest(\"hex\");\n const identityKeys = [...new Set(identities)];\n const hashes = [...new Set(identityHashes)];\n const requested = [\n ...identityKeys\n .filter((key) => !current || (!current.has(key) && !current.has(hashToken(key))))\n .map((key) => ({ hash: identityHash(key), pathLock: key.startsWith(\"path \") })),\n ...hashes.filter((hash) => !current || !current.has(`\\u0000${hash}`)).map((hash) => ({ hash, pathLock: false })),\n ]\n .filter((entry, index, entries) => entries.findIndex((candidate) => candidate.hash === entry.hash) === index)\n .sort(\n (left, right) =>\n Number(left.pathLock) - Number(right.pathLock) ||\n this.captureWriteLockPathForHash(left.hash).localeCompare(this.captureWriteLockPathForHash(right.hash))\n );\n const physicalMissing = requested.map((entry) => entry.hash);\n if (current && requested.length > 0) {\n const held = [...current]\n .filter((token) => token.startsWith(\"\\u0000\"))\n .map((token) => {\n const hash = token.slice(1);\n const pathLock = [...current].some(\n (key) => !key.startsWith(\"\\u0000\") && key.startsWith(\"path \") && hashToken(key) === token\n );\n return { hash, pathLock };\n });\n const requestedFirst = requested[0];\n const heldLast = held\n .sort(\n (left, right) =>\n Number(left.pathLock) - Number(right.pathLock) ||\n this.captureWriteLockPathForHash(left.hash).localeCompare(this.captureWriteLockPathForHash(right.hash))\n )\n .at(-1);\n if (\n heldLast &&\n requestedFirst &&\n (Number(requestedFirst.pathLock) < Number(heldLast.pathLock) ||\n (requestedFirst.pathLock === heldLast.pathLock &&\n this.captureWriteLockPathForHash(requestedFirst.hash) < this.captureWriteLockPathForHash(heldLast.hash)))\n ) {\n throw new Error(CAPTURE_WRITE_LOCK_BUSY_MESSAGE);\n }\n }\n const next = new Set(current);\n for (const key of identityKeys) {\n next.add(key);\n next.add(hashToken(key));\n }\n for (const hash of hashes) next.add(`\\u0000${hash}`);\n const run = () => this.context.run(next, task);\n if (physicalMissing.length === 0) return await run();\n return await this.withPhysicalCaptureWriteLocks(run, physicalMissing);\n }\n}\n\nexport type TombstoneBlockedMutationHost = {\n readCurrent: () => Promise<MemoryFile | null>;\n isBlocked: (memory: MemoryFile | null) => boolean;\n isQueuedReview: (memory: MemoryFile | null) => boolean;\n memoryIdentity: (memory: MemoryFile) => string;\n prepareWrite: () => Promise<string>;\n commitWrite: (marker: string) => Promise<void>;\n discardWrite: (marker: string) => Promise<void>;\n markUntrusted: () => void;\n writeStorageSecureFile: (pathname: string, fileContent: string) => Promise<void>;\n withCaptureWriteLock: (task: () => Promise<void>, identity: string | readonly string[]) => Promise<void>;\n logWarning: (message: string) => void;\n};\n\nexport type TombstoneBlockedMutation = {\n blocked: boolean;\n pathname: string;\n fileContent: string;\n identity: string | readonly string[];\n updateIndex: (rebuildMarker?: string, current?: MemoryFile | null) => Promise<void>;\n beforeIndexUpdate?: () => Promise<void>;\n coordinate?: boolean;\n};\n\nexport async function runTombstoneBlockedMutation(\n host: TombstoneBlockedMutationHost,\n mutation: TombstoneBlockedMutation\n): Promise<void> {\n let lockIdentity: string | readonly string[] = mutation.identity;\n for (;;) {\n let retryIdentity: string | undefined;\n const mutate = async (): Promise<void> => {\n const current = await host.readCurrent();\n const currentBlocked = host.isBlocked(current);\n const currentQueuedReview = host.isQueuedReview(current);\n if (current !== null && (mutation.coordinate === true || currentBlocked || currentQueuedReview)) {\n const currentIdentity = host.memoryIdentity(current);\n const heldIdentities = Array.isArray(lockIdentity) ? lockIdentity : [lockIdentity];\n if (!heldIdentities.includes(currentIdentity)) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n const rebuildMarker = mutation.blocked || currentBlocked ? await host.prepareWrite() : undefined;\n try {\n await host.writeStorageSecureFile(mutation.pathname, mutation.fileContent);\n } catch (err) {\n if (rebuildMarker) {\n try {\n await host.discardWrite(rebuildMarker);\n } catch (cleanupError) {\n host.markUntrusted();\n host.logWarning(`storage.tombstoneBlocked failed to clear write marker: ${cleanupError}`);\n }\n }\n throw err;\n }\n if (rebuildMarker) {\n try {\n await host.commitWrite(rebuildMarker);\n } catch (err) {\n host.markUntrusted();\n host.logWarning(`storage.tombstoneBlocked committed write marker failed: ${err}`);\n }\n }\n if (rebuildMarker) await mutation.beforeIndexUpdate?.();\n await mutation.updateIndex(rebuildMarker, currentBlocked && current !== null ? current : undefined);\n };\n await host.withCaptureWriteLock(mutate, lockIdentity);\n if (retryIdentity === undefined) return;\n const identities = Array.isArray(lockIdentity) ? [...lockIdentity, retryIdentity] : [lockIdentity, retryIdentity];\n lockIdentity = [...new Set(identities)];\n }\n}\n\nexport function tombstoneBlocked(frontmatter: MemoryFrontmatter): boolean {\n return frontmatter.status === \"pending_review\" && Boolean(frontmatter.blockedBy);\n}\n\nexport function isQueuedReviewFrontmatter(frontmatter: MemoryFrontmatter): boolean {\n return frontmatter.status === \"pending_review\" && (frontmatter.tags ?? []).includes(\"queued-review\");\n}\n\nexport function isQueuedReviewMemory(memory: MemoryFile | null): memory is MemoryFile {\n return memory !== null && isQueuedReviewFrontmatter(memory.frontmatter);\n}\n","import { createHash, randomUUID, type Hash } from \"node:crypto\";\nimport { unlink } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { log } from \"../logger.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport { markProjectedMemoryPathInvalid } from \"../memory-projection-store.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport { pathMayCarryEntityRefs, requestEntityCanonicalIdReconcile } from \"./entity-canonical-id-references.js\";\nimport { withRawEntityPageMutation } from \"./entity-canonical-id-lock.js\";\nimport { readMaybeEncryptedFileFromChunks, writeMaybeEncryptedFileFromChunks } from \"../secure-store/secure-fs.js\";\nimport * as archiveMutation from \"../archive-mutation-version.js\";\nimport {\n buildExplicitCaptureDedupKey,\n buildCapturePathLockIdentity,\n captureIdentityHash,\n tombstoneBlocked,\n isQueuedReviewMemory,\n runTombstoneBlockedMutation,\n type TombstoneBlockedMutationHost,\n} from \"./tombstone-blocked-capture-mutation.js\";\nimport { TombstoneBlockedCaptureIndex } from \"./tombstone-blocked-capture-index.js\";\nimport type { TombstoneBlockedCaptureIndexOptions } from \"./tombstone-blocked-capture-index.js\";\n\nconst OFFLINE_SYNC_BUFFER_LIMIT_BYTES = 1_048_576;\nconst OFFLINE_SYNC_STAGE_READ_BYTES = 64 * 1024;\nconst OFFLINE_SYNC_FRONTMATTER_DELIMITER = Buffer.from(\"\\n---\\n\", \"utf8\");\n\nconst CASED_CHARACTER = /\\p{Cased}/u;\nconst CASE_IGNORABLE_CHARACTER = /\\p{Case_Ignorable}/u;\n\ntype StreamedOfflineSyncIdentity = {\n identityHash: string;\n};\n\ntype PreparedOfflineSyncChunks = {\n after: MemoryFile | null;\n chunks: AsyncIterable<Buffer>;\n stagePath?: string;\n streamedIdentity?: StreamedOfflineSyncIdentity;\n};\n\ntype ExplicitContentNormalizerSink = {\n write: (chunk: string) => void;\n beginConditionalSigma: () => void;\n resolveConditionalSigma: (useFinalSigma: boolean) => void;\n};\n\nfunction createExplicitContentNormalizer(sink: ExplicitContentNormalizerSink): {\n push: (text: string) => void;\n finish: () => void;\n} {\n let started = false;\n let pendingSpace = false;\n let output = \"\";\n let precededByCased = false;\n let pendingSigma = false;\n const flush = () => {\n if (output.length > 0) {\n sink.write(output);\n output = \"\";\n }\n };\n const emit = (text: string) => {\n for (const character of text) {\n if (/\\s/u.test(character)) {\n if (started) pendingSpace = true;\n continue;\n }\n if (pendingSpace) {\n output += \" \";\n pendingSpace = false;\n }\n output += character;\n started = true;\n if (output.length >= OFFLINE_SYNC_STAGE_READ_BYTES) flush();\n }\n };\n const resolveSigma = (followedByCased: boolean) => {\n flush();\n sink.resolveConditionalSigma(!followedByCased);\n pendingSigma = false;\n };\n const push = (text: string) => {\n for (const character of text) {\n const caseIgnorable = CASE_IGNORABLE_CHARACTER.test(character);\n const cased = CASED_CHARACTER.test(character);\n if (pendingSigma) {\n if (caseIgnorable) {\n emit(character.toLowerCase());\n continue;\n }\n resolveSigma(cased);\n }\n if (character === \"Σ\" && precededByCased) {\n flush();\n sink.beginConditionalSigma();\n pendingSigma = true;\n precededByCased = true;\n continue;\n }\n emit(character.toLowerCase());\n if (!caseIgnorable) precededByCased = cased;\n }\n };\n return {\n push,\n finish() {\n if (pendingSigma) resolveSigma(false);\n flush();\n },\n };\n}\n\nasync function forEachStagedTextChunk(\n stagePath: string,\n offset: number,\n onText: (text: string) => void,\n key: Buffer | null,\n memoryDir: string\n): Promise<void> {\n const decoder = new TextDecoder(\"utf-8\");\n let remaining = offset;\n for await (const chunk of readMaybeEncryptedFileFromChunks(stagePath, key, memoryDir)) {\n const textChunk = remaining >= chunk.length ? null : chunk.subarray(remaining);\n remaining = Math.max(0, remaining - chunk.length);\n if (textChunk === null || textChunk.length === 0) continue;\n const text = decoder.decode(textChunk, { stream: true });\n if (text.length > 0) onText(text);\n }\n const finalText = decoder.decode();\n if (finalText.length > 0) onText(finalText);\n}\n\nasync function findStagedBodyOffset(stagePath: string, key: Buffer | null, memoryDir: string): Promise<number | null> {\n let scannedBytes = 0;\n let tail = Buffer.alloc(0);\n for await (const chunk of readMaybeEncryptedFileFromChunks(stagePath, key, memoryDir)) {\n const window = tail.length > 0 ? Buffer.concat([tail, chunk]) : chunk;\n const windowStart = scannedBytes - tail.length;\n for (let searchFrom = 0; ; ) {\n const delimiterStart = window.indexOf(OFFLINE_SYNC_FRONTMATTER_DELIMITER, searchFrom);\n if (delimiterStart < 0) break;\n if (windowStart + delimiterStart >= 4) {\n return windowStart + delimiterStart + OFFLINE_SYNC_FRONTMATTER_DELIMITER.length;\n }\n searchFrom = delimiterStart + 1;\n }\n scannedBytes += chunk.length;\n const tailLength = Math.min(OFFLINE_SYNC_FRONTMATTER_DELIMITER.length - 1, window.length);\n tail = Buffer.from(window.subarray(window.length - tailLength));\n }\n return null;\n}\n\nasync function readStagedPrefix(\n stagePath: string,\n byteLimit: number,\n key: Buffer | null,\n memoryDir: string\n): Promise<Buffer> {\n const chunks: Buffer[] = [];\n let bytesRead = 0;\n for await (const chunk of readMaybeEncryptedFileFromChunks(stagePath, key, memoryDir)) {\n const length = Math.min(chunk.length, byteLimit - bytesRead);\n if (length > 0) chunks.push(chunk.subarray(0, length));\n bytesRead += length;\n if (bytesRead >= byteLimit) break;\n }\n return Buffer.concat(chunks, bytesRead);\n}\n\nexport type OfflineSyncMemoryParser = (filePath: string, content: Buffer) => MemoryFile | null;\n\nexport function parseTombstoneBlockedOfflineSyncMemory(\n filePath: string,\n content: Buffer,\n memoryDir: string,\n parseFrontmatter: (raw: string) => { frontmatter: MemoryFrontmatter; content: string } | null,\n normalizeFrontmatterForPath: (frontmatter: MemoryFrontmatter, pathRel: string, content?: string) => MemoryFrontmatter,\n toMemoryPathRel: (baseDir: string, filePath: string) => string\n): MemoryFile | null {\n const parsed = parseFrontmatter(content.toString(\"utf8\"));\n if (!parsed) return null;\n return {\n path: filePath,\n frontmatter: normalizeFrontmatterForPath(parsed.frontmatter, toMemoryPathRel(memoryDir, filePath), parsed.content),\n content: parsed.content,\n };\n}\n\nexport abstract class TombstoneBlockedCaptureIndexHost {\n private tombstoneBlockedCaptureIndex: TombstoneBlockedCaptureIndex | null = null;\n protected abstract tombstoneBlockedCaptureIndexOptions(): TombstoneBlockedCaptureIndexOptions;\n protected abstract writeStorageSecureFile(\n filePath: string,\n content: string | Buffer,\n forceEncrypt?: boolean\n ): Promise<void>;\n protected abstract assertManagedStoragePath(filePath: string, method: string): string;\n protected abstract notifyCatalogWriteForPath(filePath: string): void;\n protected abstract readMemoryByPath(filePath: string): Promise<MemoryFile | null>;\n protected abstract invalidateAllMemoriesCache(): void;\n protected abstract invalidateKnowledgeIndexCache(): void;\n protected abstract invalidateColdMemoriesCache(): void;\n protected abstract bumpArtifactWriteVersion(): number;\n protected abstract bumpMemoryStatusVersion(): void;\n protected abstract bumpMemoryCorpusVersion(): void;\n protected abstract markFactHashIndexNotAuthoritative(): void;\n protected abstract deleteManagedStorageFile(filePath: string, deletionMtimeMs?: number | null): Promise<boolean>;\n protected abstract writeManagedStorageFile(filePath: string, write: () => Promise<void>): Promise<void>;\n\n private async writeStorageSecureFileChunks(filePath: string, chunks: AsyncIterable<Buffer>): Promise<void> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n await writeMaybeEncryptedFileFromChunks(\n filePath,\n chunks,\n options.secureStoreWriteKeyProvider(),\n {},\n options.memoryDir\n );\n this.notifyCatalogWriteForPath(filePath);\n }\n\n protected getTombstoneBlockedCaptureIndex(): TombstoneBlockedCaptureIndex {\n if (this.tombstoneBlockedCaptureIndex === null) {\n this.tombstoneBlockedCaptureIndex = new TombstoneBlockedCaptureIndex(this.tombstoneBlockedCaptureIndexOptions());\n }\n return this.tombstoneBlockedCaptureIndex;\n }\n async withTombstoneBlockedCaptureWriteLock<T>(\n task: () => Promise<T>,\n identity?: string | readonly string[]\n ): Promise<T> {\n return await this.getTombstoneBlockedCaptureIndex().withCaptureWriteLock(task, identity);\n }\n\n protected async withTombstoneBlockedCaptureWriteLockAndHashes<T>(\n task: () => Promise<T>,\n identity: string | readonly string[] | undefined,\n identityHashes: readonly string[]\n ): Promise<T> {\n return await this.getTombstoneBlockedCaptureIndex().withCaptureWriteLockAndHashes(task, identity, identityHashes);\n }\n\n private async writeTombstoneBlockedMutation(\n blocked: boolean,\n pathname: string,\n fileContent: string,\n identity: string | readonly string[],\n updateIndex: (rebuildMarker?: string, current?: MemoryFile | null) => Promise<void>,\n beforeIndexUpdate?: () => Promise<void>,\n coordinate = false\n ): Promise<void> {\n const host: TombstoneBlockedMutationHost = {\n readCurrent: () => this.readMemoryByPath(pathname),\n isBlocked: (memory) => this.isTombstoneBlockedMemory(memory),\n isQueuedReview: (memory) => isQueuedReviewMemory(memory),\n memoryIdentity: (memory) => this.offlineSyncMemoryIdentity(memory),\n prepareWrite: () => this.getTombstoneBlockedCaptureIndex().prepareWrite(),\n commitWrite: (marker) => this.getTombstoneBlockedCaptureIndex().commitWrite(marker),\n discardWrite: (marker) => this.getTombstoneBlockedCaptureIndex().discardWrite(marker),\n markUntrusted: () => this.getTombstoneBlockedCaptureIndex().markUntrusted(),\n writeStorageSecureFile: (target, content) => this.writeStorageSecureFile(target, content),\n withCaptureWriteLock: (task, lockIdentity) => this.withTombstoneBlockedCaptureWriteLock(task, lockIdentity),\n logWarning: (message) => log.warn(message),\n };\n await runTombstoneBlockedMutation(host, {\n blocked,\n pathname,\n fileContent,\n identity,\n updateIndex,\n beforeIndexUpdate,\n coordinate,\n });\n }\n\n protected async writeTombstoneBlockedMemory(\n pathname: string,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n beforeIndexUpdate?: () => Promise<void>\n ): Promise<void> {\n await this.writeTombstoneBlockedMutation(\n tombstoneBlocked(frontmatter),\n pathname,\n fileContent,\n [\n buildCapturePathLockIdentity(pathname),\n buildExplicitCaptureDedupKey(content, frontmatter.category, frontmatter.sourceConnector),\n ],\n (rebuildMarker) =>\n this.getTombstoneBlockedCaptureIndex().addWrittenMemory(pathname, frontmatter, content, rebuildMarker),\n beforeIndexUpdate\n );\n }\n\n protected async withTombstoneBlockedMemoryPathLock<T>(\n pathname: string,\n task: (current: MemoryFile | null) => Promise<T>,\n additionalPathnames: readonly string[] = []\n ): Promise<T> {\n let lockIdentities = [pathname, ...additionalPathnames].map(buildCapturePathLockIdentity);\n for (;;) {\n let retryIdentity: string | undefined;\n let result: T | undefined;\n await this.withTombstoneBlockedCaptureWriteLock(async () => {\n const current = await this.readMemoryByPath(pathname);\n if (current !== null) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (!lockIdentities.includes(currentIdentity)) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n result = await task(current);\n }, lockIdentities);\n if (retryIdentity !== undefined) {\n lockIdentities = [...new Set([...lockIdentities, retryIdentity])];\n continue;\n }\n return result!;\n }\n }\n\n protected async writeTombstoneBlockedChunk(\n pathname: string,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n findDuplicate: () => Promise<MemoryFile | null>,\n afterWrite: (current: MemoryFile | null) => Promise<void>\n ): Promise<string> {\n const incomingIdentity = buildExplicitCaptureDedupKey(content, frontmatter.category, frontmatter.sourceConnector);\n let lockIdentities = [buildCapturePathLockIdentity(pathname), incomingIdentity];\n for (;;) {\n let retryIdentity: string | undefined;\n let result = frontmatter.id;\n await this.withTombstoneBlockedCaptureWriteLock(async () => {\n const current = await this.readMemoryByPath(pathname);\n if (current !== null) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (!lockIdentities.includes(currentIdentity)) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n if (tombstoneBlocked(frontmatter)) {\n const duplicate = await findDuplicate();\n if (duplicate) {\n result = duplicate.frontmatter.id;\n return;\n }\n }\n await this.writeTombstoneBlockedMemory(pathname, fileContent, frontmatter, content);\n await afterWrite(current);\n }, lockIdentities);\n if (retryIdentity === undefined) return result;\n lockIdentities = [...new Set([...lockIdentities, retryIdentity])];\n }\n }\n\n protected async writeTombstoneBlockedUpdate(\n before: MemoryFile,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n beforeIndexUpdate?: () => Promise<void>\n ): Promise<void> {\n await this.writeTombstoneBlockedMutation(\n tombstoneBlocked(before.frontmatter) || tombstoneBlocked(frontmatter),\n before.path,\n fileContent,\n [\n buildCapturePathLockIdentity(before.path),\n this.offlineSyncMemoryIdentity(before),\n buildExplicitCaptureDedupKey(content, frontmatter.category, frontmatter.sourceConnector),\n ],\n (rebuildMarker, current) =>\n this.getTombstoneBlockedCaptureIndex().syncUpdatedMemory(\n current ?? before,\n frontmatter,\n content,\n rebuildMarker\n ),\n beforeIndexUpdate,\n true\n );\n }\n\n protected async writeTombstoneBlockedFrontmatter(\n before: MemoryFile,\n fileContent: string,\n frontmatter: MemoryFrontmatter,\n beforeIndexUpdate?: () => Promise<void>\n ): Promise<void> {\n await this.writeTombstoneBlockedMutation(\n tombstoneBlocked(before.frontmatter) || tombstoneBlocked(frontmatter),\n before.path,\n fileContent,\n [\n buildCapturePathLockIdentity(before.path),\n this.offlineSyncMemoryIdentity(before),\n buildExplicitCaptureDedupKey(before.content, frontmatter.category, frontmatter.sourceConnector),\n ],\n (rebuildMarker, current) =>\n this.getTombstoneBlockedCaptureIndex().syncUpdatedFrontmatter(current ?? before, frontmatter, rebuildMarker),\n beforeIndexUpdate,\n true\n );\n }\n\n private isTombstoneBlockedMemory(memory: MemoryFile | null): memory is MemoryFile {\n return memory !== null && memory.frontmatter.status === \"pending_review\" && Boolean(memory.frontmatter.blockedBy);\n }\n\n private offlineSyncMemoryIdentity(memory: MemoryFile): string {\n return buildExplicitCaptureDedupKey(\n memory.content,\n memory.frontmatter.category,\n memory.frontmatter.sourceConnector\n );\n }\n private async isDuplicateTombstoneBlockedOfflineSync(\n target: string,\n incoming: MemoryFile,\n streamedIdentity?: StreamedOfflineSyncIdentity\n ): Promise<boolean> {\n const before = await this.readMemoryByPath(target);\n const duplicate = streamedIdentity\n ? true\n : await this.getTombstoneBlockedCaptureIndex().has(\n incoming.content,\n incoming.frontmatter.category,\n incoming.frontmatter.sourceConnector\n );\n if (!duplicate) return false;\n const incomingIdentity = streamedIdentity?.identityHash ?? this.offlineSyncMemoryIdentity(incoming);\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const existing = [...(await options.readAllMemories()), ...(await options.readAllColdMemories())];\n const exactMatch = existing.some(\n (memory) =>\n this.isTombstoneBlockedMemory(memory) &&\n (streamedIdentity ? captureIdentityHash(memory) : this.offlineSyncMemoryIdentity(memory)) === incomingIdentity\n );\n if (!exactMatch) return false;\n if (before === null) return true;\n if (!this.isTombstoneBlockedMemory(before)) return false;\n const beforeIdentity = streamedIdentity ? captureIdentityHash(before) : this.offlineSyncMemoryIdentity(before);\n if (beforeIdentity !== incomingIdentity) return false;\n return streamedIdentity\n ? isDeepStrictEqual(before.frontmatter, incoming.frontmatter)\n : before.content === incoming.content && isDeepStrictEqual(before.frontmatter, incoming.frontmatter);\n }\n\n private async invalidateAfterOfflineSyncMutation(\n filePath: string,\n ownedMarker?: string,\n archiveChanged = true\n ): Promise<void> {\n this.invalidateAllMemoriesCache();\n this.invalidateKnowledgeIndexCache();\n this.markFactHashIndexNotAuthoritative();\n if (filePath.includes(`${path.sep}cold${path.sep}`)) {\n this.invalidateColdMemoriesCache();\n }\n await this.rebuildTombstoneBlockedCaptureAfterInvalidationForPath(filePath, ownedMarker);\n if (filePath.includes(`${path.sep}artifacts${path.sep}`)) {\n this.bumpArtifactWriteVersion();\n }\n const memoryDir = this.tombstoneBlockedCaptureIndexOptions().memoryDir;\n archiveMutation.bumpArchiveMutationForPath(memoryDir, archiveChanged, filePath);\n this.bumpMemoryStatusVersion();\n }\n\n protected async runTombstoneBlockedArchive(\n memory: MemoryFile,\n task: (current: MemoryFile, markDurable: () => void) => Promise<string | null>\n ): Promise<string | null> {\n let archivedPath: string | null = null;\n const archived = await this.runTombstoneBlockedInvalidation(memory, async (current, rebuildMarker, markDurable) => {\n let archiveDurable = false;\n const markArchiveDurable = () => {\n archiveDurable = true;\n markDurable();\n };\n archivedPath = await task(current, markArchiveDurable);\n if (rebuildMarker !== undefined && (archivedPath !== null || archiveDurable)) {\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);\n } else if (rebuildMarker !== undefined) {\n const index = this.getTombstoneBlockedCaptureIndex();\n try {\n await index.discardWrite(rebuildMarker);\n } catch {\n index.markUntrusted();\n }\n }\n return archivedPath !== null;\n });\n return archived ? archivedPath : null;\n }\n\n protected async runTombstoneBlockedInvalidation(\n memory: MemoryFile,\n task: (current: MemoryFile, rebuildMarker: string | undefined, markDurable: () => void) => Promise<boolean>,\n propagateErrors = false,\n coordinate = false\n ): Promise<boolean> {\n let lockIdentities = [\n buildCapturePathLockIdentity(memory.path),\n ...(coordinate || this.isTombstoneBlockedMemory(memory) || isQueuedReviewMemory(memory)\n ? [this.offlineSyncMemoryIdentity(memory)]\n : []),\n ];\n for (;;) {\n const attempt = async () => {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const current =\n (await this.readMemoryByPath(memory.path)) ??\n (await options.readAllMemories()).find((candidate) => candidate.frontmatter.id === memory.frontmatter.id) ??\n (await options.readAllColdMemories()).find((candidate) => candidate.frontmatter.id === memory.frontmatter.id);\n if (!current) return { result: false };\n const blocked = this.isTombstoneBlockedMemory(current);\n const queuedReview = isQueuedReviewMemory(current);\n if (blocked || queuedReview) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (!lockIdentities.includes(currentIdentity)) return { retryIdentity: currentIdentity };\n }\n const blockedIndex = blocked ? this.getTombstoneBlockedCaptureIndex() : null;\n let rebuildMarker: string | undefined;\n let durable = false;\n try {\n if (blockedIndex) rebuildMarker = await blockedIndex.prepareWrite();\n const result = await task(current, rebuildMarker, () => {\n durable = true;\n });\n if (!result && rebuildMarker && !durable && blockedIndex) {\n try {\n await blockedIndex.discardWrite(rebuildMarker);\n } catch {\n blockedIndex.markUntrusted();\n }\n }\n return { result };\n } catch (error) {\n if (rebuildMarker && !durable && blockedIndex) {\n try {\n await blockedIndex.discardWrite(rebuildMarker);\n } catch {\n blockedIndex.markUntrusted();\n }\n }\n if (propagateErrors) throw error;\n return { result: false };\n }\n };\n const result = await this.withTombstoneBlockedCaptureWriteLock(attempt, lockIdentities);\n if (result.retryIdentity !== undefined) {\n lockIdentities = [...new Set([...lockIdentities, result.retryIdentity])];\n continue;\n }\n return result.result;\n }\n }\n async deleteMemoryForMaintenance(\n memory: MemoryFile,\n shouldDelete: (current: MemoryFile) => boolean = () => true\n ): Promise<MemoryFile | null> {\n let deleted: MemoryFile | null = null;\n const removed = await this.runTombstoneBlockedInvalidation(\n memory,\n async (current, rebuildMarker, markDurable) => {\n if (!shouldDelete(current)) return false;\n if (!(await this.deleteManagedStorageFile(current.path))) return false;\n markDurable();\n deleted = current;\n const memoryDir = this.tombstoneBlockedCaptureIndexOptions().memoryDir;\n archiveMutation.bumpArchiveMutationForPath(memoryDir, true, current.path);\n markProjectedMemoryPathInvalid(memoryDir, current.frontmatter.id);\n this.invalidateAllMemoriesCache();\n if (current.path.includes(`${path.sep}cold${path.sep}`)) {\n this.invalidateColdMemoriesCache();\n }\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);\n this.bumpMemoryCorpusVersion();\n this.bumpMemoryStatusVersion();\n return true;\n },\n true,\n true\n );\n return removed ? deleted : null;\n }\n\n protected async runTombstoneBlockedOfflineSyncMutation(\n target: string,\n after: MemoryFile | null,\n write: () => Promise<boolean | void>,\n coordinate = false,\n streamedIdentity?: StreamedOfflineSyncIdentity\n ): Promise<void> {\n for (;;) {\n const before = await this.readMemoryByPath(target);\n const targetIdentity = before === null ? undefined : this.offlineSyncMemoryIdentity(before);\n const afterIdentity = after === null || streamedIdentity ? undefined : this.offlineSyncMemoryIdentity(after);\n const mustCoordinate =\n coordinate || targetIdentity !== undefined || afterIdentity !== undefined || streamedIdentity !== undefined;\n const identities = [\n ...(mustCoordinate ? [buildCapturePathLockIdentity(target)] : []),\n ...(targetIdentity === undefined ? [] : [targetIdentity]),\n ...(afterIdentity === undefined ? [] : [afterIdentity]),\n ];\n let retryIdentity: string | undefined;\n const mutate = async (): Promise<void> => {\n const current = await this.readMemoryByPath(target);\n if (current !== null) {\n const currentIdentity = this.offlineSyncMemoryIdentity(current);\n if (currentIdentity !== targetIdentity) {\n retryIdentity = currentIdentity;\n return;\n }\n }\n if (\n this.isTombstoneBlockedMemory(after) &&\n (await this.isDuplicateTombstoneBlockedOfflineSync(target, after, streamedIdentity))\n ) {\n return;\n }\n const affectsBlockedIndex =\n coordinate || this.isTombstoneBlockedMemory(current) || this.isTombstoneBlockedMemory(after);\n const marker = affectsBlockedIndex ? await this.getTombstoneBlockedCaptureIndex().prepareWrite() : undefined;\n let durable = false;\n try {\n const changed = await write();\n durable = true;\n if (marker) {\n try {\n await this.getTombstoneBlockedCaptureIndex().commitWrite(marker);\n } catch (err) {\n this.getTombstoneBlockedCaptureIndex().markUntrusted();\n log.warn(`storage.offlineSyncFile committed write marker failed: ${err}`);\n }\n }\n await this.invalidateAfterOfflineSyncMutation(target, marker, changed !== false);\n } catch (err) {\n if (marker && !durable) {\n try {\n await this.getTombstoneBlockedCaptureIndex().discardWrite(marker);\n } catch (cleanupError) {\n this.getTombstoneBlockedCaptureIndex().markUntrusted();\n log.warn(`storage.offlineSyncFile failed to clear write marker: ${cleanupError}`);\n }\n }\n throw err;\n }\n };\n if (!mustCoordinate) {\n await mutate();\n } else if (streamedIdentity) {\n await this.withTombstoneBlockedCaptureWriteLockAndHashes(mutate, identities, [streamedIdentity.identityHash]);\n } else {\n await this.withTombstoneBlockedCaptureWriteLock(mutate, identities);\n }\n if (retryIdentity !== undefined) continue;\n return;\n }\n }\n\n protected async writeTombstoneBlockedOfflineSyncFile(target: string, content: Buffer): Promise<void> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const after = options.parseMemory?.(target, content) ?? null;\n await withRawEntityPageMutation(path.dirname(options.stateDir), target, async () => {\n await this.runTombstoneBlockedOfflineSyncMutation(\n target,\n after,\n () => this.writeManagedStorageFile(target, () => this.writeStorageSecureFile(target, content))\n );\n });\n }\n\n private async prepareTombstoneBlockedOfflineSyncChunks(\n target: string,\n chunks: AsyncIterable<Buffer>\n ): Promise<PreparedOfflineSyncChunks> {\n const parseMemory = this.tombstoneBlockedCaptureIndexOptions().parseMemory;\n if (!parseMemory) return { after: null, chunks };\n\n const iterator = chunks[Symbol.asyncIterator]();\n const buffered: Buffer[] = [];\n let bufferedBytes = 0;\n let firstOverflow: Buffer | undefined;\n for (;;) {\n const next = await iterator.next();\n if (next.done) break;\n if (bufferedBytes + next.value.length > OFFLINE_SYNC_BUFFER_LIMIT_BYTES) {\n firstOverflow = next.value;\n break;\n }\n bufferedBytes += next.value.length;\n buffered.push(next.value);\n }\n const overflow = firstOverflow;\n if (overflow === undefined) {\n let after: MemoryFile | null = null;\n try {\n after = parseMemory(target, Buffer.concat(buffered));\n } catch {\n after = null;\n }\n const replay = (async function* (): AsyncIterable<Buffer> {\n for (const chunk of buffered) yield chunk;\n })();\n return { after, chunks: replay };\n }\n\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const stagePath = path.join(\n options.stateDir,\n \"tombstone-blocked-capture\",\n \"offline-sync-staging\",\n `${randomUUID()}.stage`\n );\n const stagedChunks = (async function* (): AsyncIterable<Buffer> {\n for (const chunk of buffered) yield chunk;\n yield overflow;\n for (;;) {\n const next = await iterator.next();\n if (next.done) break;\n yield next.value;\n }\n })();\n try {\n await writeMaybeEncryptedFileFromChunks(\n stagePath,\n stagedChunks,\n options.secureStoreWriteKeyProvider(),\n { atomic: false },\n options.memoryDir\n );\n return await this.describeStagedOfflineSyncChunks(target, stagePath, parseMemory);\n } catch (err) {\n await unlink(stagePath).catch(() => {});\n throw err;\n }\n }\n\n private async describeStagedOfflineSyncChunks(\n target: string,\n stagePath: string,\n parseMemory: OfflineSyncMemoryParser\n ): Promise<PreparedOfflineSyncChunks> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const key = options.secureStoreKeyProvider();\n const bodyOffset = await findStagedBodyOffset(stagePath, key, options.memoryDir);\n if (bodyOffset === null) {\n return { after: null, chunks: this.readStagedOfflineSyncChunks(stagePath), stagePath };\n }\n const prefix = await readStagedPrefix(stagePath, bodyOffset, key, options.memoryDir);\n let after: MemoryFile | null = null;\n try {\n after = parseMemory(target, prefix.subarray(0, bodyOffset));\n } catch {\n after = null;\n }\n if (after === null) {\n return { after: null, chunks: this.readStagedOfflineSyncChunks(stagePath), stagePath };\n }\n const streamedIdentity = await this.computeStagedOfflineSyncIdentity(stagePath, bodyOffset, after);\n return {\n after,\n chunks: this.readStagedOfflineSyncChunks(stagePath),\n stagePath,\n streamedIdentity,\n };\n }\n\n private async computeStagedOfflineSyncIdentity(\n stagePath: string,\n bodyOffset: number,\n after: MemoryFile\n ): Promise<StreamedOfflineSyncIdentity> {\n let normalizedLength = 0;\n const countNormalizer = createExplicitContentNormalizer({\n write: (chunk) => {\n normalizedLength += chunk.length;\n },\n beginConditionalSigma: () => {\n normalizedLength += 1;\n },\n resolveConditionalSigma: () => {},\n });\n const options = this.tombstoneBlockedCaptureIndexOptions();\n const key = options.secureStoreKeyProvider();\n await forEachStagedTextChunk(stagePath, bodyOffset, (text) => countNormalizer.push(text), key, options.memoryDir);\n countNormalizer.finish();\n\n const category = after.frontmatter.category;\n const connector = after.frontmatter.sourceConnector?.trim() ?? \"\";\n const encode = (label: string, value: string): string => `${label} ${value.length} ${value}`;\n const identityPrefix = [\n encode(\"category\", category),\n encode(\"connector\", connector),\n `content ${normalizedLength} `,\n ].join(\" \");\n let identityHash = createHash(\"sha256\");\n let normalSigmaIdentityHash: Hash | undefined;\n identityHash.update(identityPrefix);\n const identityNormalizer = createExplicitContentNormalizer({\n write: (chunk) => {\n identityHash.update(chunk);\n normalSigmaIdentityHash?.update(chunk);\n },\n beginConditionalSigma: () => {\n normalSigmaIdentityHash = identityHash.copy().update(\"σ\");\n identityHash.update(\"ς\");\n },\n resolveConditionalSigma: (useFinalSigma) => {\n if (!useFinalSigma) {\n if (normalSigmaIdentityHash === undefined) throw new Error(\"conditional sigma hash state is missing\");\n identityHash = normalSigmaIdentityHash;\n }\n normalSigmaIdentityHash = undefined;\n },\n });\n await forEachStagedTextChunk(\n stagePath,\n bodyOffset,\n (text) => identityNormalizer.push(text),\n key,\n options.memoryDir\n );\n identityNormalizer.finish();\n return {\n identityHash: identityHash.digest(\"hex\"),\n };\n }\n\n private async *readStagedOfflineSyncChunks(stagePath: string): AsyncIterable<Buffer> {\n const options = this.tombstoneBlockedCaptureIndexOptions();\n for await (const chunk of readMaybeEncryptedFileFromChunks(\n stagePath,\n options.secureStoreKeyProvider(),\n options.memoryDir\n )) {\n yield chunk;\n }\n }\n\n protected async writeTombstoneBlockedOfflineSyncFileChunks(\n target: string,\n chunks: AsyncIterable<Buffer>\n ): Promise<void> {\n const coordinate = this.getTombstoneBlockedCaptureIndex().shouldRebuildAfterInvalidationForPath(target);\n const prepared: PreparedOfflineSyncChunks = coordinate\n ? await this.prepareTombstoneBlockedOfflineSyncChunks(target, chunks)\n : { after: null, chunks };\n const streamedIdentity = prepared.streamedIdentity;\n const baseDir = path.dirname(this.tombstoneBlockedCaptureIndexOptions().stateDir);\n try {\n await withRawEntityPageMutation(baseDir, target, async () => {\n await this.runTombstoneBlockedOfflineSyncMutation(\n target,\n prepared.after,\n () => this.writeManagedStorageFile(target, () => this.writeStorageSecureFileChunks(target, prepared.chunks)),\n coordinate,\n streamedIdentity\n );\n });\n } finally {\n if (prepared.stagePath !== undefined) await unlink(prepared.stagePath).catch(() => {});\n }\n }\n\n async writeOfflineSyncFile(filePath: string, content: Buffer): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.writeOfflineSyncFile\");\n await this.writeTombstoneBlockedOfflineSyncFile(target, content);\n await this.requestSyncReconcileIfMigrationPath(target);\n }\n\n async writeOfflineSyncFileChunks(filePath: string, chunks: AsyncIterable<Buffer>): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.writeOfflineSyncFileChunks\");\n await this.writeTombstoneBlockedOfflineSyncFileChunks(target, chunks);\n await this.requestSyncReconcileIfMigrationPath(target);\n }\n\n /**\n * Opaque replicated bytes can restore legacy memory references or entity\n * relationship targets. Other sync traffic must not request reconciliation.\n */\n private async requestSyncReconcileIfMigrationPath(target: string): Promise<void> {\n const stateDir = this.tombstoneBlockedCaptureIndexOptions().stateDir;\n if (!pathMayCarryEntityRefs(path.dirname(stateDir), target)) return;\n await requestEntityCanonicalIdReconcile(stateDir);\n }\n\n async deleteOfflineSyncFile(filePath: string, deletionMtimeMs?: number | null): Promise<void> {\n const target = this.assertManagedStoragePath(filePath, \"storage.deleteOfflineSyncFile\");\n await this.deleteTombstoneBlockedOfflineSyncFile(target, deletionMtimeMs);\n await this.requestSyncReconcileIfMigrationPath(target);\n }\n\n protected async deleteTombstoneBlockedOfflineSyncFile(\n target: string,\n deletionMtimeMs?: number | null\n ): Promise<void> {\n const stateDir = this.tombstoneBlockedCaptureIndexOptions().stateDir;\n await withRawEntityPageMutation(path.dirname(stateDir), target, async () => {\n await this.runTombstoneBlockedOfflineSyncMutation(target, null, async () => {\n return await this.deleteManagedStorageFile(target, deletionMtimeMs);\n });\n });\n }\n\n async checkTombstoneBlockedExplicitCapture(\n ...args: [string, string, string?]\n ): Promise<{ has: boolean; authoritative: boolean }> {\n return this.getTombstoneBlockedCaptureIndex().check(...args);\n }\n\n async hasTombstoneBlockedExplicitCapture(...args: [string, string, string?]): Promise<boolean> {\n return this.getTombstoneBlockedCaptureIndex().has(...args);\n }\n\n async isTombstoneBlockedExplicitCaptureIndexAuthoritative(): Promise<boolean> {\n return this.getTombstoneBlockedCaptureIndex().isAuthoritative();\n }\n\n protected async rebuildTombstoneBlockedCaptureAfterInvalidationForPath(\n filePath: string,\n ownedMarker?: string\n ): Promise<void> {\n const index = this.getTombstoneBlockedCaptureIndex();\n if (index.shouldRebuildAfterInvalidationForPath(filePath)) {\n await this.rebuildTombstoneBlockedCaptureAfterInvalidation(ownedMarker);\n }\n }\n protected async rebuildTombstoneBlockedCaptureAfterInvalidation(ownedMarker?: string): Promise<void> {\n await this.getTombstoneBlockedCaptureIndex().rebuildAfterInvalidation(ownedMarker);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, readdir, rename, stat, unlink, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { log } from \"../logger.js\";\nimport type { MemoryFile, MemoryFrontmatter } from \"../types.js\";\nimport { RECALL_FALLBACK_DIRS } from \"../utils/category-dir.js\";\nimport { isErrnoCode } from \"../utils/errno.js\";\nimport type { withHeldFileLock } from \"../utils/serialize-mutations.js\";\nimport {\n CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS,\n ContentHashIndex,\n type ContentHashIndexLockOptions,\n} from \"./content-hash-index.js\";\nimport {\n TombstoneBlockedCaptureWriteLock,\n buildExplicitCaptureDedupKey,\n} from \"./tombstone-blocked-capture-mutation.js\";\nimport type { OfflineSyncMemoryParser } from \"./tombstone-blocked-capture-sync.js\";\nexport {\n buildExplicitCaptureDedupKey,\n isTombstoneBlockedCaptureWriteLockBusy,\n normalizeExplicitCaptureContent,\n} from \"./tombstone-blocked-capture-mutation.js\";\nexport {\n parseTombstoneBlockedOfflineSyncMemory,\n type OfflineSyncMemoryParser,\n TombstoneBlockedCaptureIndexHost,\n} from \"./tombstone-blocked-capture-sync.js\";\n\nconst REBUILD_MAX_ATTEMPTS = 3;\nconst execFileAsync = promisify(execFile);\nconst REBUILD_RETRY_BASE_MS = 50;\n\nconst ABANDONED_MARKER_MIN_AGE_MS = 60_000;\nconst MARKER_PROCESS_START_TOLERANCE_MS = 2_000;\nconst DOTNET_UNIX_EPOCH_TICKS = 621_355_968_000_000_000;\nconst MARKER_PROCESS_STARTED_AT_MS = Date.now() - process.uptime() * 1000;\n\ntype RebuildMarker = {\n path: string;\n committed: boolean;\n pid?: number;\n ownerId?: string;\n createdAt?: number;\n processStartedAtMs?: number;\n malformed?: boolean;\n};\n\nexport type TombstoneBlockedCaptureIndexOptions = {\n readonly stateDir: string;\n readonly memoryDir: string;\n readonly secureStoreKeyProvider: () => Buffer | null;\n readonly secureStoreWriteKeyProvider: () => Buffer | null;\n readonly lockOptions: () => ContentHashIndexLockOptions;\n readonly readAllMemories: () => Promise<MemoryFile[]>;\n readonly readAllColdMemories: () => Promise<MemoryFile[]>;\n readonly parseMemory?: OfflineSyncMemoryParser;\n readonly withHeldFileLock?: typeof withHeldFileLock;\n};\n\n/**\n * Durable targeted deduplication for tombstone-blocked explicit captures.\n *\n * The active fact-hash index intentionally excludes blocked rows. This small\n * companion index keeps the blocked identity visible without making every\n * authoritative active-index miss scan the full corpus.\n */\nexport class TombstoneBlockedCaptureIndex {\n private readonly options: TombstoneBlockedCaptureIndexOptions;\n private index: ContentHashIndex | null = null;\n private loadPromise: Promise<ContentHashIndex> | null = null;\n private refreshPromise: Promise<ContentHashIndex> | null = null;\n private authoritative = false;\n private readonly captureWriteLock: TombstoneBlockedCaptureWriteLock;\n\n constructor(options: TombstoneBlockedCaptureIndexOptions) {\n this.options = options;\n this.captureWriteLock = new TombstoneBlockedCaptureWriteLock(options);\n }\n\n private createIndex(): ContentHashIndex {\n return new ContentHashIndex(\n path.join(this.options.stateDir, \"tombstone-blocked-capture\"),\n this.options.secureStoreKeyProvider,\n this.options.secureStoreWriteKeyProvider,\n this.options.memoryDir,\n this.options.lockOptions()\n );\n }\n\n private indexPath(): string {\n return path.join(this.options.stateDir, \"tombstone-blocked-capture\", \"fact-hashes.txt\");\n }\n\n private rebuildMarkerPath(): string {\n return path.join(this.options.stateDir, \"tombstone-blocked-capture\", \"rebuild-required\");\n }\n\n private async readRebuildMarkers(): Promise<RebuildMarker[]> {\n try {\n const entries = (await readdir(this.rebuildMarkerPath())).filter((entry) => !entry.startsWith(\".\"));\n return (\n await Promise.all(\n entries.map(async (entry) => {\n const markerPath = path.join(this.rebuildMarkerPath(), entry);\n try {\n const raw = (await readFile(markerPath, \"utf8\")).trim();\n if (raw === \"committed\") return { path: markerPath, committed: true };\n let value: Record<string, unknown>;\n let malformed = false;\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n malformed = true;\n value = {};\n } else {\n value = parsed as Record<string, unknown>;\n }\n } catch {\n malformed = true;\n value = {};\n }\n const state = value.state;\n if (state !== \"pending\" && state !== \"committed\") malformed = true;\n const markerStat = await stat(markerPath).catch(() => null);\n // A torn payload can lose its JSON metadata, but the atomic\n // marker filename and filesystem mtime still identify its owner\n // and age. Preserve both so stale malformed markers can be\n // reaped without treating a fresh pre-commit gap as abandoned.\n const createdAt =\n typeof value.createdAt === \"number\" && Number.isFinite(value.createdAt)\n ? value.createdAt\n : markerStat?.mtimeMs;\n if (typeof value.pid !== \"number\" || !Number.isInteger(value.pid)) malformed = true;\n const ownerId =\n typeof value.ownerId === \"string\" && value.ownerId.length > 0\n ? value.ownerId\n : path.basename(markerPath);\n if (typeof value.ownerId !== \"string\" || value.ownerId.length === 0) malformed = true;\n const processStartedAtMs =\n typeof value.processStartedAtMs === \"number\" &&\n Number.isFinite(value.processStartedAtMs) &&\n value.processStartedAtMs > 0\n ? value.processStartedAtMs\n : undefined;\n return {\n path: markerPath,\n committed: state === \"committed\",\n ...(typeof value.pid === \"number\" && Number.isInteger(value.pid) ? { pid: value.pid } : {}),\n ...(ownerId.length > 0 ? { ownerId } : {}),\n ...(typeof createdAt === \"number\" && Number.isFinite(createdAt) ? { createdAt } : {}),\n ...(processStartedAtMs === undefined ? {} : { processStartedAtMs }),\n ...(malformed ? { malformed: true } : {}),\n };\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return null;\n throw err;\n }\n })\n )\n ).filter((marker): marker is RebuildMarker => marker !== null);\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) return [];\n throw err;\n }\n }\n private async isAbandonedMarker(marker: RebuildMarker): Promise<boolean> {\n if (marker.committed || marker.createdAt === undefined) return false;\n if (Date.now() - marker.createdAt < ABANDONED_MARKER_MIN_AGE_MS) return false;\n if (marker.malformed) return true;\n return marker.pid !== undefined && !(await this.isProcessAlive(marker.pid, marker.processStartedAtMs));\n }\n\n private async isProcessAlive(pid: number, processStartedAtMs?: number): Promise<boolean> {\n try {\n process.kill(pid, 0);\n } catch (err) {\n return !isErrnoCode(err, \"ESRCH\");\n }\n if (processStartedAtMs === undefined) return true;\n const runningStartedAtMs = await this.readProcessStartedAtMs(pid);\n if (runningStartedAtMs === null) return true;\n return runningStartedAtMs <= processStartedAtMs + MARKER_PROCESS_START_TOLERANCE_MS;\n }\n private async readProcessStartedAtMs(pid: number): Promise<number | null> {\n try {\n if (process.platform === \"win32\") {\n const { stdout } = await execFileAsync(\n \"powershell.exe\",\n [\n \"-NoLogo\",\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-Command\",\n `(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks`,\n ],\n { encoding: \"utf8\", timeout: 1_000 }\n );\n const ticks = Number(stdout.trim());\n return Number.isFinite(ticks) ? (ticks - DOTNET_UNIX_EPOCH_TICKS) / 10_000 : null;\n }\n const { stdout } = await execFileAsync(\"ps\", [\"-p\", String(pid), \"-o\", \"lstart=\"], {\n encoding: \"utf8\",\n timeout: 1_000,\n });\n const output = stdout.trim();\n if (!output) return null;\n const startedAtMs = Date.parse(output);\n return Number.isFinite(startedAtMs) ? startedAtMs : null;\n } catch {\n return null;\n }\n }\n\n private async getClearableRebuildMarkerPaths(markers: readonly RebuildMarker[]): Promise<string[]> {\n const paths = await Promise.all(\n markers.map(async (marker) => (marker.committed || (await this.isAbandonedMarker(marker)) ? marker.path : null))\n );\n return paths.filter((markerPath): markerPath is string => markerPath !== null);\n }\n\n private async getRebuildMarkers(): Promise<RebuildMarker[]> {\n return await this.readRebuildMarkers();\n }\n\n // A pending marker protects the pre-commit gap; only committed markers are safe for another writer to clear.\n private async writeMarkerAtomically(markerPath: string, payload: string): Promise<void> {\n const temporaryPath = `${markerPath}.tmp-${process.pid}-${randomUUID()}`;\n try {\n await writeFile(temporaryPath, payload, \"utf8\");\n await rename(temporaryPath, markerPath);\n } finally {\n await unlink(temporaryPath).catch((err: unknown) => {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n });\n }\n }\n\n private async markRebuildRequired(committed = false): Promise<string> {\n const markerDir = this.rebuildMarkerPath();\n await mkdir(markerDir, { recursive: true });\n const ownerId = randomUUID();\n const markerPath = path.join(markerDir, ownerId);\n await this.writeMarkerAtomically(\n markerPath,\n `${JSON.stringify({\n state: committed ? \"committed\" : \"pending\",\n pid: process.pid,\n ownerId,\n createdAt: Date.now(),\n processStartedAtMs: MARKER_PROCESS_STARTED_AT_MS,\n })}\\n`\n );\n return markerPath;\n }\n\n private async markRebuildCommitted(markerPath: string): Promise<void> {\n await this.writeMarkerAtomically(\n markerPath,\n `${JSON.stringify({\n state: \"committed\",\n pid: process.pid,\n ownerId: path.basename(markerPath),\n createdAt: Date.now(),\n processStartedAtMs: MARKER_PROCESS_STARTED_AT_MS,\n })}\\n`\n );\n }\n\n private async clearRebuildRequired(markerPaths: readonly string[]): Promise<void> {\n await Promise.all(\n markerPaths.map(async (markerPath) => {\n try {\n await unlink(markerPath);\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n }\n })\n );\n }\n\n private async hasRebuildRequired(excludedMarkers: readonly string[] = []): Promise<boolean> {\n const excluded = new Set(excludedMarkers);\n return (await this.getRebuildMarkers()).some((marker) => !excluded.has(marker.path));\n }\n\n private async setAuthoritative(rebuilt: boolean): Promise<void> {\n this.authoritative = rebuilt && !(await this.getRebuildMarkers()).some((marker) => !marker.committed);\n }\n private isBlocked(memory: MemoryFile): boolean {\n return memory.frontmatter.status === \"pending_review\" && Boolean(memory.frontmatter.blockedBy);\n }\n\n private async rebuild(index: ContentHashIndex): Promise<boolean> {\n return await index.rebuildUnderLock(async () => {\n index.clear();\n const existing = [...(await this.options.readAllMemories()), ...(await this.options.readAllColdMemories())];\n for (const memory of existing) {\n if (!this.isBlocked(memory)) continue;\n index.add(\n buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)\n );\n }\n });\n }\n\n private async hasPersistedIndexOrMarkers(): Promise<boolean> {\n try {\n await stat(this.indexPath());\n return true;\n } catch (err) {\n if (!isErrnoCode(err, \"ENOENT\")) throw err;\n return (await this.readRebuildMarkers()).length > 0;\n }\n }\n\n private async getIndex(): Promise<ContentHashIndex> {\n if (this.index) return this.index;\n if (!this.loadPromise) {\n const index = this.createIndex();\n this.loadPromise = (async () => {\n await index.load();\n const rebuildMarkers = await this.getRebuildMarkers();\n const clearableRebuildMarkers = await this.getClearableRebuildMarkerPaths(rebuildMarkers);\n let persisted = !index.requiresFormatMigration;\n try {\n await stat(this.indexPath());\n if (rebuildMarkers.length > 0) persisted = false;\n } catch (err) {\n if (isErrnoCode(err, \"ENOENT\")) persisted = false;\n else throw err;\n }\n if (!persisted) {\n const lockOptions = this.options.lockOptions();\n const maxAttempts = lockOptions.retryMaxAttempts ?? REBUILD_MAX_ATTEMPTS;\n const baseMs = lockOptions.retryBaseMs ?? REBUILD_RETRY_BASE_MS;\n let rebuilt = false;\n for (let attempt = 0; attempt < maxAttempts; attempt += 1) {\n rebuilt = await this.rebuild(index);\n if (rebuilt || attempt === maxAttempts - 1) break;\n const wait = Math.min(baseMs * 2 ** attempt, CONTENT_HASH_INDEX_RETRY_MAX_DELAY_MS);\n const delayState = Promise.withResolvers<void>();\n setTimeout(delayState.resolve, wait);\n await delayState.promise;\n }\n if (!rebuilt) {\n throw new Error(\"tombstone-blocked capture index rebuild lock unavailable\");\n }\n await this.clearRebuildRequired(clearableRebuildMarkers);\n }\n await this.setAuthoritative(true);\n this.index = index;\n return index;\n })().catch((err) => {\n this.loadPromise = null;\n throw err;\n });\n }\n return this.loadPromise;\n }\n\n async withCaptureWriteLock<T>(task: () => Promise<T>, identity?: string | readonly string[]): Promise<T> {\n return await this.captureWriteLock.withCaptureWriteLock(task, identity);\n }\n\n async withCaptureWriteLockHashes<T>(task: () => Promise<T>, identityHashes: readonly string[]): Promise<T> {\n return await this.captureWriteLock.withCaptureWriteLockHashes(task, identityHashes);\n }\n async withCaptureWriteLockAndHashes<T>(\n task: () => Promise<T>,\n identity: string | readonly string[] | undefined,\n identityHashes: readonly string[]\n ): Promise<T> {\n return await this.captureWriteLock.withCaptureWriteLockAndHashes(task, identity, identityHashes);\n }\n\n private async reload(): Promise<ContentHashIndex> {\n if (!this.refreshPromise) {\n this.refreshPromise = (async () => {\n this.index = null;\n this.loadPromise = null;\n return await this.getIndex();\n })().finally(() => {\n this.refreshPromise = null;\n });\n }\n return this.refreshPromise;\n }\n\n /** Return blocked-row membership and authority from one index snapshot. */\n async check(\n content: string,\n category: string,\n sourceConnector?: string\n ): Promise<{ has: boolean; authoritative: boolean }> {\n const key = buildExplicitCaptureDedupKey(content, category, sourceConnector);\n let index = await this.getIndex();\n if ((await this.hasRebuildRequired()) || !(await index.isDiskFingerprintCurrent())) {\n index = await this.reload();\n }\n return { has: index.has(key), authoritative: this.authoritative };\n }\n\n /** Return whether a blocked row matches this explicit-capture identity. */\n async has(content: string, category: string, sourceConnector?: string): Promise<boolean> {\n return (await this.check(content, category, sourceConnector)).has;\n }\n\n /** Return whether the in-memory index is safe to answer an authoritative miss. */\n async isAuthoritative(): Promise<boolean> {\n const index = await this.getIndex();\n if ((await this.hasRebuildRequired()) || !(await index.isDiskFingerprintCurrent())) {\n await this.reload();\n }\n return this.authoritative;\n }\n\n /** Reserve durable rebuild intent before a blocked memory file is committed. */\n async prepareWrite(): Promise<string> {\n return this.markRebuildRequired();\n }\n\n /** Mark a prepared write committed once its memory file is durable. */\n async commitWrite(rebuildMarker: string): Promise<void> {\n await this.markRebuildCommitted(rebuildMarker);\n }\n\n /** Drop a pending marker when the protected memory write never commits. */\n async discardWrite(rebuildMarker: string): Promise<void> {\n await this.clearRebuildRequired([rebuildMarker]);\n }\n\n /** Add a newly persisted blocked row to the durable targeted index. */\n async add(memory: MemoryFile, rebuildMarker?: string): Promise<void> {\n if (!this.isBlocked(memory)) return;\n let index = await this.getIndex();\n if (\n (await this.hasRebuildRequired(rebuildMarker ? [rebuildMarker] : [])) ||\n !(await index.isDiskFingerprintCurrent())\n ) {\n index = await this.reload();\n }\n index.add(\n buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)\n );\n const marker = rebuildMarker ?? (await this.markRebuildRequired(true));\n if (rebuildMarker) await this.markRebuildCommitted(rebuildMarker);\n await index.saveMergingWithDisk();\n await index.flushReconcileRetry();\n if (index.hasPendingChanges) {\n this.markUntrusted();\n return;\n }\n await this.clearRebuildRequired([marker]);\n await this.setAuthoritative(true);\n }\n\n /** Rebuild the index after a blocked row changes or is removed. */\n async rebuildIfLoaded(ownedMarker?: string): Promise<void> {\n const index = this.index ?? ((await this.hasPersistedIndexOrMarkers()) ? this.getIndex() : null);\n if (!index) return;\n const rebuildMarkers = await this.getRebuildMarkers();\n const rebuildMarker = await this.markRebuildRequired(true);\n const clearableRebuildMarkers = await this.getClearableRebuildMarkerPaths(rebuildMarkers);\n const rebuilt = await this.rebuild(await index);\n if (rebuilt) {\n await this.clearRebuildRequired([\n ...clearableRebuildMarkers,\n ...(ownedMarker === undefined || clearableRebuildMarkers.includes(ownedMarker) ? [] : [ownedMarker]),\n rebuildMarker,\n ]);\n }\n await this.setAuthoritative(rebuilt);\n }\n\n /** Rebuild when either side of a write is blocked and its identity changed. */\n async sync(before: MemoryFile, after: MemoryFile, rebuildMarker?: string): Promise<void> {\n const beforeBlocked = this.isBlocked(before);\n const afterBlocked = this.isBlocked(after);\n if (!beforeBlocked && !afterBlocked) return;\n const beforeKey = buildExplicitCaptureDedupKey(\n before.content,\n before.frontmatter.category,\n before.frontmatter.sourceConnector\n );\n const afterKey = buildExplicitCaptureDedupKey(\n after.content,\n after.frontmatter.category,\n after.frontmatter.sourceConnector\n );\n if (beforeBlocked && afterBlocked && beforeKey === afterKey) {\n if (rebuildMarker) {\n await this.markRebuildCommitted(rebuildMarker);\n await this.clearRebuildRequired([rebuildMarker]);\n }\n return;\n }\n const existingMarkers = await this.getRebuildMarkers();\n const marker = rebuildMarker ?? (await this.markRebuildRequired(true));\n const clearableExistingMarkers = await this.getClearableRebuildMarkerPaths(existingMarkers);\n if (rebuildMarker) await this.markRebuildCommitted(rebuildMarker);\n const rebuilt = await this.rebuild(await this.getIndex());\n if (rebuilt) {\n await this.clearRebuildRequired([...clearableExistingMarkers, marker]);\n }\n await this.setAuthoritative(rebuilt);\n }\n markUntrusted(): void {\n this.authoritative = false;\n }\n\n private async failOpen(operation: string, action: () => Promise<void>): Promise<void> {\n try {\n await action();\n } catch (err) {\n this.markUntrusted();\n log.warn(`storage.${operation} completed but failed to update tombstone-blocked capture index: ${err}`);\n }\n }\n\n async addWrittenMemory(\n pathname: string,\n frontmatter: MemoryFrontmatter,\n content: string,\n rebuildMarker?: string\n ): Promise<void> {\n await this.failOpen(\"writeMemory\", () => this.add({ path: pathname, frontmatter, content }, rebuildMarker));\n }\n\n async rebuildAfterInvalidation(ownedMarker?: string): Promise<void> {\n await this.failOpen(\"invalidateMemory\", () => this.rebuildIfLoaded(ownedMarker));\n }\n\n async syncUpdatedMemory(\n before: MemoryFile,\n frontmatter: MemoryFrontmatter,\n content: string,\n rebuildMarker?: string\n ): Promise<void> {\n await this.failOpen(\"updateMemory\", () => this.sync(before, { ...before, frontmatter, content }, rebuildMarker));\n }\n\n async syncUpdatedFrontmatter(\n before: MemoryFile,\n frontmatter: MemoryFrontmatter,\n rebuildMarker?: string\n ): Promise<void> {\n await this.failOpen(\"writeMemoryFrontmatter\", () => this.sync(before, { ...before, frontmatter }, rebuildMarker));\n }\n shouldRebuildAfterInvalidationForPath(filePath: string): boolean {\n const relative = path.relative(path.resolve(this.options.memoryDir), path.resolve(filePath));\n const category = relative.split(path.sep)[0];\n return category === \"cold\" || RECALL_FALLBACK_DIRS.includes(category);\n }\n}\n"],"mappings":"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","names":["createHash","randomUUID","unlink","path","mkdir","path","path","stdout","mkdir","path","result","randomUUID","unlink","createHash"]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-35NN3ZFA.js";
5
5
  import {
6
6
  composeMemoryEnvelope
7
- } from "./chunk-5V6IXHPI.js";
7
+ } from "./chunk-NSVDUN76.js";
8
8
  import {
9
9
  log
10
10
  } from "./chunk-3WCASNQZ.js";
@@ -399,4 +399,4 @@ export {
399
399
  isValidResolutionVerb,
400
400
  executeResolution
401
401
  };
402
- //# sourceMappingURL=chunk-BAKXNQ3C.js.map
402
+ //# sourceMappingURL=chunk-KRTY3ENI.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-VEWZZM3H.js";
8
8
  import {
9
9
  buildFactProvenance
10
- } from "./chunk-QBSFOKY6.js";
10
+ } from "./chunk-VOELBUS4.js";
11
11
 
12
12
  // src/extraction-source-grounding.ts
13
13
  function applyExtractionSourceGrounding2(result, sourceText, assertionSourceText = sourceText, roleAssertionSources, messageTimestamp, options) {
@@ -70,4 +70,4 @@ export {
70
70
  attachExtractionProvenance,
71
71
  filterExtractionResultBySource2 as filterExtractionResultBySource
72
72
  };
73
- //# sourceMappingURL=chunk-NK5RGJ65.js.map
73
+ //# sourceMappingURL=chunk-L4DLLKPN.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  StorageManager
3
- } from "./chunk-WD5B5AIE.js";
3
+ } from "./chunk-6R4G7N4S.js";
4
4
  import {
5
5
  getCachedRuleMemories,
6
6
  setCachedRuleMemories
@@ -119,4 +119,4 @@ export {
119
119
  compareVerifiedSemanticRuleResults,
120
120
  searchVerifiedSemanticRules
121
121
  };
122
- //# sourceMappingURL=chunk-VFSAWRMZ.js.map
122
+ //# sourceMappingURL=chunk-LJS7KUPV.js.map
@@ -2,8 +2,13 @@ import {
2
2
  serializeMutations,
3
3
  withHeldFileLock
4
4
  } from "./chunk-FFAZ2XFU.js";
5
+ import {
6
+ computeLegacyContentHash
7
+ } from "./chunk-5FVVY2EB.js";
5
8
 
6
9
  // src/lifecycle/tombstones.ts
10
+ var TOMBSTONE_NORMALIZER_VERSION = 2;
11
+ var DEFAULT_LEGACY_MIGRATION_LIMIT = 1e4;
7
12
  var TOMBSTONE_PREFIX = "tomb";
8
13
  function newTombstoneId() {
9
14
  return `${TOMBSTONE_PREFIX}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -46,6 +51,12 @@ function parseTombstoneLine(line) {
46
51
  createdAt: e.createdAt,
47
52
  createdBy: e.createdBy
48
53
  };
54
+ if (typeof e.currentContentHashAlias === "string") {
55
+ out.currentContentHashAlias = e.currentContentHashAlias;
56
+ }
57
+ if (typeof e.normalizerVersion === "number" && Number.isInteger(e.normalizerVersion)) {
58
+ out.normalizerVersion = e.normalizerVersion;
59
+ }
49
60
  if (typeof e.operationKey === "string") out.operationKey = e.operationKey;
50
61
  if (typeof e.entityRef === "string") out.entityRef = e.entityRef;
51
62
  if (typeof e.supersessionKey === "string") out.supersessionKey = e.supersessionKey;
@@ -58,6 +69,10 @@ var TombstoneStore = class {
58
69
  this.namespace = namespace;
59
70
  this.options = options;
60
71
  this.io = io;
72
+ const limit = this.options.legacyMigrationLimit;
73
+ if (limit !== void 0 && (!Number.isFinite(limit) || !Number.isInteger(limit) || limit < 0)) {
74
+ throw new Error("legacyMigrationLimit must be a finite non-negative integer");
75
+ }
61
76
  this.lockStaleMs = this.options.lockStaleMs ?? 3e4;
62
77
  this.lockMaxWaitMs = this.options.lockMaxWaitMs ?? 5e3;
63
78
  this.lockHeartbeatMs = this.options.lockHeartbeatMs ?? Math.max(100, Math.floor(this.lockStaleMs / 3));
@@ -118,30 +133,104 @@ var TombstoneStore = class {
118
133
  this.loadPromise = null;
119
134
  }
120
135
  }
121
- async loadInternal() {
136
+ async loadInternal(migrateLegacy = true) {
122
137
  this.recordFileMtime();
123
138
  let raw;
124
139
  try {
125
140
  raw = await this.io.read(this.filePath);
126
141
  } catch (err) {
127
142
  const code = err?.code;
128
- if (code !== "ENOENT") {
129
- }
143
+ if (code !== "ENOENT") throw err;
130
144
  this.loaded = true;
131
145
  return;
132
146
  }
147
+ const initial = this.parseEntries(raw);
148
+ const migrated = migrateLegacy ? await this.migrateLegacyEntries(initial) : initial;
133
149
  this.resetIndex();
134
- let corrupted = 0;
150
+ for (const entry of migrated.entries) this.indexEntry(entry);
151
+ this.corruptedLines = migrated.corruptedLines;
152
+ this.loaded = true;
153
+ }
154
+ parseEntries(raw) {
155
+ const entries = [];
156
+ let corruptedLines = 0;
135
157
  for (const line of raw.split("\n")) {
136
158
  const entry = parseTombstoneLine(line);
137
159
  if (!entry) {
138
- if (line.trim().length > 0) corrupted += 1;
160
+ if (line.trim().length > 0) corruptedLines += 1;
139
161
  continue;
140
162
  }
141
- this.indexEntry(entry);
163
+ entries.push(entry);
142
164
  }
143
- this.corruptedLines = corrupted;
144
- this.loaded = true;
165
+ return { entries, corruptedLines };
166
+ }
167
+ /**
168
+ * Re-index pre-Unicode records from retired source content.
169
+ * Source reads stay bounded, but every batch finishes before the store
170
+ * publishes its in-memory index. Missing sources remain eligible on restart.
171
+ */
172
+ async migrateLegacyEntries(initial) {
173
+ const limit = this.options.legacyMigrationLimit ?? DEFAULT_LEGACY_MIGRATION_LIMIT;
174
+ if (limit === 0 || !this.options.sourceContentsForMemoryIds) return initial;
175
+ const sourceMemoryIds = [];
176
+ const requested = /* @__PURE__ */ new Set();
177
+ for (const entry of initial.entries) {
178
+ if (entry.kind !== "tombstone" || entry.normalizerVersion === TOMBSTONE_NORMALIZER_VERSION) {
179
+ continue;
180
+ }
181
+ if (requested.has(entry.sourceMemoryId)) continue;
182
+ requested.add(entry.sourceMemoryId);
183
+ sourceMemoryIds.push(entry.sourceMemoryId);
184
+ }
185
+ if (sourceMemoryIds.length === 0) return initial;
186
+ const sourceContents = /* @__PURE__ */ new Map();
187
+ for (let offset = 0; offset < sourceMemoryIds.length; offset += limit) {
188
+ const batch = sourceMemoryIds.slice(offset, offset + limit);
189
+ const fetched = await this.options.sourceContentsForMemoryIds(batch);
190
+ for (const [sourceMemoryId, content] of fetched) sourceContents.set(sourceMemoryId, content);
191
+ }
192
+ return await serializeMutations(
193
+ `tombstone:${this.filePath}`,
194
+ () => this.withWriteLock(async () => {
195
+ const latestRaw = await this.io.read(this.filePath);
196
+ const latest = this.parseEntries(latestRaw);
197
+ let changed = false;
198
+ const migrateEntry = (entry) => {
199
+ if (entry.kind !== "tombstone" || entry.normalizerVersion === TOMBSTONE_NORMALIZER_VERSION || !requested.has(entry.sourceMemoryId)) {
200
+ return entry;
201
+ }
202
+ const resolved = sourceContents.get(entry.sourceMemoryId);
203
+ if (resolved === void 0) return entry;
204
+ const candidates = typeof resolved === "string" ? [resolved] : resolved;
205
+ const matches = candidates.filter(
206
+ (source2) => entry.contentHash === this.options.hashContent(source2) || entry.contentHash === computeLegacyContentHash(source2)
207
+ );
208
+ const explicitPrimary = matches.length === 0 && entry.contentHash !== this.options.hashContent(entry.normalizedText);
209
+ const source = matches[0] ?? (explicitPrimary ? candidates[0] : void 0);
210
+ if (source === void 0) return entry;
211
+ const currentHash = this.options.hashContent(source);
212
+ const alias = explicitPrimary ? currentHash : matches.map((candidate) => this.options.hashContent(candidate)).find((hash) => hash !== currentHash);
213
+ changed = true;
214
+ return {
215
+ ...entry,
216
+ contentHash: explicitPrimary ? entry.contentHash : currentHash,
217
+ ...alias ? { currentContentHashAlias: alias } : {},
218
+ normalizedText: this.options.normalizeText(source),
219
+ normalizerVersion: TOMBSTONE_NORMALIZER_VERSION
220
+ };
221
+ };
222
+ const serialized = latestRaw.split("\n").map((line) => {
223
+ const entry = parseTombstoneLine(line);
224
+ if (!entry) return line;
225
+ const migrated = migrateEntry(entry);
226
+ return migrated === entry ? line : JSON.stringify(migrated);
227
+ }).join("\n");
228
+ if (!changed) return latest;
229
+ await this.io.write(this.filePath, serialized);
230
+ this.markWritten();
231
+ return this.parseEntries(serialized);
232
+ })
233
+ );
145
234
  }
146
235
  resetIndex() {
147
236
  this.entries = [];
@@ -167,8 +256,13 @@ var TombstoneStore = class {
167
256
  return;
168
257
  }
169
258
  const ns = entry.namespace;
170
- if (entry.contentHash) this.byHash.set(`${ns}\0${entry.contentHash}`, entry.id);
171
- if (entry.normalizedText) this.byNormalized.set(`${ns}\0${entry.normalizedText}`, entry.id);
259
+ if (entry.normalizerVersion === TOMBSTONE_NORMALIZER_VERSION) {
260
+ if (entry.contentHash) this.byHash.set(`${ns}\0${entry.contentHash}`, entry.id);
261
+ if (entry.currentContentHashAlias) {
262
+ this.byHash.set(`${ns}\0${entry.currentContentHashAlias}`, entry.id);
263
+ }
264
+ if (entry.normalizedText) this.byNormalized.set(`${ns}\0${entry.normalizedText}`, entry.id);
265
+ }
172
266
  if (entry.entityRef && entry.supersessionKey) {
173
267
  this.byKey.set(keyedTierKey(ns, entry.entityRef, entry.supersessionKey), entry.id);
174
268
  }
@@ -181,15 +275,11 @@ var TombstoneStore = class {
181
275
  }
182
276
  /**
183
277
  * Cross-process staleness probe (#1579). If the file's mtime advanced since
184
- * the last load/own-write, a peer process appended and our in-memory index is
185
- * stale — invalidate AND reload in place so the next lookup sees the new
186
- * entries. Best-effort: a stat error is swallowed (the loaded index is
187
- * retained rather than crashing the write path). No-op when no `stat` was
188
- * injected or when the mtime is unchanged. After our own append/revoke/rebuild
189
- * `markWritten` records the new mtime, so this probe does not fire for our
190
- * own writes (only for peer-process appends).
278
+ * the last load/own-write, a peer process appended and our in-memory index
279
+ * is stale — invalidate and reload before the next access. Mutation callers
280
+ * pass `migrate: false` to avoid nested serializer/lock acquisition.
191
281
  */
192
- async ensureFreshAgainstDisk() {
282
+ async ensureFreshAgainstDisk(options = {}) {
193
283
  if (!this.io.stat) return;
194
284
  let mtimeMs;
195
285
  try {
@@ -200,7 +290,11 @@ var TombstoneStore = class {
200
290
  if (mtimeMs === this.fileMtimeMs && this.loaded) return;
201
291
  this.fileMtimeMs = mtimeMs;
202
292
  this.invalidate();
203
- await this.load();
293
+ if (options.migrate === false) {
294
+ await this.loadInternal(false);
295
+ } else {
296
+ await this.load();
297
+ }
204
298
  }
205
299
  /**
206
300
  * Record the file mtime after THIS process writes (append / revoke / rebuild)
@@ -230,13 +324,17 @@ var TombstoneStore = class {
230
324
  await this.load();
231
325
  const createdAt = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
232
326
  const id = newTombstoneId();
327
+ const currentHash = this.options.hashContent(input.rawContent);
328
+ const currentNormalizedText = this.options.normalizeText(input.rawContent);
233
329
  const entry = {
234
330
  id,
331
+ ...input.contentHash && input.contentHash !== currentHash ? { currentContentHashAlias: currentHash } : {},
235
332
  kind: "tombstone",
236
333
  reason: input.reason,
237
334
  sourceMemoryId: input.sourceMemoryId,
238
- contentHash: input.contentHash ?? this.options.hashContent(input.rawContent),
239
- normalizedText: this.options.normalizeText(input.rawContent),
335
+ contentHash: input.contentHash ?? currentHash,
336
+ normalizedText: currentNormalizedText,
337
+ normalizerVersion: TOMBSTONE_NORMALIZER_VERSION,
240
338
  ...input.entityRef ? { entityRef: input.entityRef } : {},
241
339
  ...input.supersessionKey ? { supersessionKey: input.supersessionKey } : {},
242
340
  ...input.operationKey ? { operationKey: input.operationKey } : {},
@@ -247,6 +345,7 @@ var TombstoneStore = class {
247
345
  await this.serializeAppend(entry);
248
346
  this.indexEntry(entry);
249
347
  this.markWritten();
348
+ await this.migrateLoadedLegacyEntries();
250
349
  return id;
251
350
  }
252
351
  /**
@@ -272,6 +371,7 @@ var TombstoneStore = class {
272
371
  await this.serializeAppend(entry);
273
372
  this.indexEntry(entry);
274
373
  this.markWritten();
374
+ await this.migrateLoadedLegacyEntries();
275
375
  return id;
276
376
  }
277
377
  serializeAppend(entry) {
@@ -279,11 +379,30 @@ var TombstoneStore = class {
279
379
  return serializeMutations(
280
380
  `tombstone:${this.filePath}`,
281
381
  () => this.withWriteLock(async () => {
282
- await this.ensureFreshAgainstDisk();
382
+ await this.ensureFreshAgainstDisk({ migrate: false });
283
383
  await this.io.append(this.filePath, line);
284
384
  })
285
385
  );
286
386
  }
387
+ async migrateLoadedLegacyEntries() {
388
+ const initial = {
389
+ entries: [...this.entries],
390
+ corruptedLines: this.corruptedLines
391
+ };
392
+ if (!initial.entries.some(
393
+ (entry) => entry.kind === "tombstone" && entry.normalizerVersion !== TOMBSTONE_NORMALIZER_VERSION
394
+ )) {
395
+ return;
396
+ }
397
+ try {
398
+ const migrated = await this.migrateLegacyEntries(initial);
399
+ this.resetIndex();
400
+ for (const entry of migrated.entries) this.indexEntry(entry);
401
+ this.corruptedLines = migrated.corruptedLines;
402
+ this.loaded = true;
403
+ } catch {
404
+ }
405
+ }
287
406
  /**
288
407
  * Acquire the cross-process tombstone write lock and run `task` under it
289
408
  * (issue #1639). Strict-fail on acquisition timeout: the secure-store append
@@ -367,6 +486,7 @@ var TombstoneStore = class {
367
486
  let best = null;
368
487
  for (const entry of this.entries) {
369
488
  if (entry.kind !== "tombstone") continue;
489
+ if (entry.normalizerVersion !== TOMBSTONE_NORMALIZER_VERSION) continue;
370
490
  if (entry.namespace !== query.namespace) continue;
371
491
  if (this.revokedIds.has(entry.id)) continue;
372
492
  if (!entry.normalizedText) continue;
@@ -418,7 +538,7 @@ var TombstoneStore = class {
418
538
  const rebuiltCount = await serializeMutations(
419
539
  `tombstone:${this.filePath}`,
420
540
  () => this.withWriteLock(async () => {
421
- await this.ensureFreshAgainstDisk();
541
+ await this.ensureFreshAgainstDisk({ migrate: false });
422
542
  const existingRevocations = this.entries.filter((e) => e.kind === "revocation");
423
543
  const foreignTombstones = this.entries.filter(
424
544
  (e) => e.kind === "tombstone" && e.namespace !== this.namespace
@@ -429,19 +549,27 @@ var TombstoneStore = class {
429
549
  existingBySource.set(`${e.sourceMemoryId}\0${e.supersessionKey ?? ""}`, e.id);
430
550
  }
431
551
  }
432
- const rebuilt = retiredMemories.map((m) => ({
433
- id: existingBySource.get(`${m.memoryId}\0${m.supersessionKey ?? ""}`) ?? newTombstoneId(),
434
- kind: "tombstone",
435
- reason: m.reason,
436
- sourceMemoryId: m.memoryId,
437
- contentHash: m.contentHash ?? this.options.hashContent(m.rawContent),
438
- normalizedText: this.options.normalizeText(m.rawContent),
439
- ...m.entityRef ? { entityRef: m.entityRef } : {},
440
- ...m.supersessionKey ? { supersessionKey: m.supersessionKey } : {},
441
- namespace: this.namespace,
442
- createdAt: m.createdAt,
443
- createdBy: m.createdBy
444
- }));
552
+ const rebuilt = retiredMemories.map((m) => {
553
+ const currentHash = this.options.hashContent(m.rawContent);
554
+ const currentNormalizedText = this.options.normalizeText(m.rawContent);
555
+ const persistedHash = m.contentHash;
556
+ const preserveOverride = persistedHash !== void 0 && persistedHash !== currentHash && persistedHash !== computeLegacyContentHash(m.rawContent);
557
+ return {
558
+ id: existingBySource.get(`${m.memoryId}\0${m.supersessionKey ?? ""}`) ?? newTombstoneId(),
559
+ ...preserveOverride ? { currentContentHashAlias: currentHash } : {},
560
+ kind: "tombstone",
561
+ reason: m.reason,
562
+ sourceMemoryId: m.memoryId,
563
+ contentHash: preserveOverride ? persistedHash : currentHash,
564
+ normalizedText: currentNormalizedText,
565
+ normalizerVersion: TOMBSTONE_NORMALIZER_VERSION,
566
+ ...m.entityRef ? { entityRef: m.entityRef } : {},
567
+ ...m.supersessionKey ? { supersessionKey: m.supersessionKey } : {},
568
+ namespace: this.namespace,
569
+ createdAt: m.createdAt,
570
+ createdBy: m.createdBy
571
+ };
572
+ });
445
573
  rebuilt.sort(
446
574
  (a, b) => a.createdAt === b.createdAt ? a.id < b.id ? -1 : a.id > b.id ? 1 : 0 : a.createdAt < b.createdAt ? -1 : 1
447
575
  );
@@ -458,6 +586,7 @@ var TombstoneStore = class {
458
586
  return rebuilt.length;
459
587
  })
460
588
  );
589
+ await this.migrateLoadedLegacyEntries();
461
590
  return rebuiltCount;
462
591
  }
463
592
  };
@@ -530,4 +659,4 @@ export {
530
659
  applyTombstoneResurrectionGate,
531
660
  buildRetiredFactTombstoneInputs
532
661
  };
533
- //# sourceMappingURL=chunk-JJRVPWFY.js.map
662
+ //# sourceMappingURL=chunk-MLPTFODV.js.map