@remnic/core 9.69.45 → 9.69.47

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 (603) hide show
  1. package/dist/access-admin-ops-surface.d.ts +15 -14
  2. package/dist/access-admin-ops-surface.js +40 -39
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +15 -14
  5. package/dist/access-authorization-probe.js +41 -40
  6. package/dist/access-boundary.d.ts +15 -14
  7. package/dist/access-boundary.js +40 -39
  8. package/dist/access-cli.js +110 -104
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.d.ts +15 -14
  12. package/dist/access-extraction-force-flush.js +40 -39
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-briefing.d.ts +15 -14
  15. package/dist/access-http-briefing.js +41 -40
  16. package/dist/access-http-lcm-compaction.d.ts +15 -14
  17. package/dist/access-http-lifecycle-flush.d.ts +15 -14
  18. package/dist/access-http-offline-stream.d.ts +15 -14
  19. package/dist/access-http-query.d.ts +2 -2
  20. package/dist/access-http-query.js +42 -41
  21. package/dist/access-http.d.ts +16 -15
  22. package/dist/access-http.js +64 -60
  23. package/dist/access-identity-continuity-surface.d.ts +11 -11
  24. package/dist/access-identity-continuity-surface.js +40 -39
  25. package/dist/access-lcm-surface.d.ts +15 -14
  26. package/dist/access-lcm-surface.js +40 -39
  27. package/dist/access-mcp-output-schemas.js +1 -1
  28. package/dist/access-mcp-shared-context-tools.d.ts +15 -14
  29. package/dist/access-mcp.d.ts +15 -14
  30. package/dist/access-mcp.js +53 -50
  31. package/dist/access-memory-search-fanout.d.ts +2 -2
  32. package/dist/{access-namespace-preflight-DDnsN22V.d.ts → access-namespace-preflight-CetF9ziA.d.ts} +1 -1
  33. package/dist/access-namespace-preflight.d.ts +3 -3
  34. package/dist/access-namespace-preflight.js +40 -39
  35. package/dist/access-observe-transcript.d.ts +11 -11
  36. package/dist/access-observe-write-category.d.ts +3 -3
  37. package/dist/access-observe-write-surface.d.ts +15 -14
  38. package/dist/access-observe-write-surface.js +40 -39
  39. package/dist/access-offline-manifest.d.ts +11 -11
  40. package/dist/access-offline-manifest.js +2 -2
  41. package/dist/access-operations-batch.js +42 -41
  42. package/dist/access-operations.d.ts +16 -15
  43. package/dist/access-operations.js +49 -47
  44. package/dist/access-recall-concurrency.d.ts +15 -14
  45. package/dist/access-recall-concurrency.js +40 -39
  46. package/dist/access-recall-response.d.ts +15 -14
  47. package/dist/access-recall-response.js +40 -39
  48. package/dist/access-recall-surface.d.ts +15 -14
  49. package/dist/access-recall-surface.js +40 -39
  50. package/dist/access-schema.d.ts +1 -1
  51. package/dist/{access-service-CDteK_Gt.d.ts → access-service-BXYrJ3pO.d.ts} +13 -10
  52. package/dist/access-service-helpers.d.ts +15 -14
  53. package/dist/access-service.d.ts +15 -14
  54. package/dist/access-service.js +40 -39
  55. package/dist/access-surface-catalog.d.ts +15 -14
  56. package/dist/access-surface-catalog.js +48 -41
  57. package/dist/access-surface-catalog.js.map +1 -1
  58. package/dist/access-wearables-meetings-surface.d.ts +4 -4
  59. package/dist/action-confidence.d.ts +1 -1
  60. package/dist/active-memory-bridge.d.ts +1 -1
  61. package/dist/active-recall.d.ts +1 -1
  62. package/dist/active-recall.js +3 -2
  63. package/dist/active-recall.js.map +1 -1
  64. package/dist/activity/digest.d.ts +1 -1
  65. package/dist/adapters/index.js +4 -4
  66. package/dist/adapters/registry.js +2 -2
  67. package/dist/ambient-provenance.d.ts +1 -1
  68. package/dist/artifact-search.d.ts +1 -1
  69. package/dist/background-generation.d.ts +1 -1
  70. package/dist/behavior-learner.d.ts +1 -1
  71. package/dist/behavior-signals.d.ts +1 -1
  72. package/dist/bootstrap.d.ts +11 -11
  73. package/dist/briefing-window.d.ts +2 -2
  74. package/dist/briefing.d.ts +2 -2
  75. package/dist/briefing.js +13 -13
  76. package/dist/buffer-surprise-report.d.ts +1 -1
  77. package/dist/buffer-turn-helpers.d.ts +1 -1
  78. package/dist/buffer.d.ts +2 -2
  79. package/dist/buffer.js +5 -5
  80. package/dist/bulk-import/index.d.ts +3 -3
  81. package/dist/calibration.d.ts +1 -1
  82. package/dist/capabilities.d.ts +1 -1
  83. package/dist/{catalog-Dl2hYqpS.d.ts → catalog-Bns9zpl3.d.ts} +1 -1
  84. package/dist/causal-behavior.d.ts +1 -1
  85. package/dist/causal-consolidation.d.ts +1 -1
  86. package/dist/causal-consolidation.js +14 -14
  87. package/dist/causal-trajectory-graph.d.ts +1 -1
  88. package/dist/{chunk-OREGA7GY.js → chunk-2JFSQWFH.js} +5 -5
  89. package/dist/chunk-2JFSQWFH.js.map +1 -0
  90. package/dist/{chunk-C3MCMFNV.js → chunk-2QX65IEC.js} +2 -2
  91. package/dist/{chunk-HBGSZ62Z.js → chunk-3RKVSECD.js} +8 -8
  92. package/dist/{chunk-7LKXP4QG.js → chunk-44BILQ7U.js} +85 -43
  93. package/dist/chunk-44BILQ7U.js.map +1 -0
  94. package/dist/{chunk-R4HFCATE.js → chunk-4LPIVP77.js} +2 -2
  95. package/dist/{chunk-PW4HTWXL.js → chunk-55XWRL6F.js} +2 -2
  96. package/dist/{chunk-E5VOKZQV.js → chunk-5KBI2MOC.js} +1 -1
  97. package/dist/{chunk-ZQ533JDE.js → chunk-6A6HSXWV.js} +2 -2
  98. package/dist/{chunk-4HTQ76O4.js → chunk-7SJCSDQ3.js} +2 -2
  99. package/dist/{chunk-A2YN3FR4.js → chunk-7YUX52XZ.js} +3 -3
  100. package/dist/{chunk-NKDQXDFL.js → chunk-AS4YKT75.js} +36 -26
  101. package/dist/chunk-AS4YKT75.js.map +1 -0
  102. package/dist/{chunk-LQVXSRAJ.js → chunk-B4EGAHHS.js} +2 -2
  103. package/dist/{chunk-EUP4AXIW.js → chunk-B6VDWDFN.js} +2 -2
  104. package/dist/{chunk-Z5YNVWRD.js → chunk-BMENHAJL.js} +2 -2
  105. package/dist/{chunk-5ZXGH2ZL.js → chunk-BXOPUJ3W.js} +2 -2
  106. package/dist/{chunk-J6NEOCQC.js → chunk-CD7VTZIG.js} +2 -2
  107. package/dist/{chunk-EC5SVM6H.js → chunk-DE4ZGH2N.js} +2 -2
  108. package/dist/{chunk-2LRO73MN.js → chunk-DRLZB3CN.js} +2 -2
  109. package/dist/{chunk-SHEHQBCG.js → chunk-DUJYRVUD.js} +638 -45
  110. package/dist/chunk-DUJYRVUD.js.map +1 -0
  111. package/dist/{chunk-Q4MI2KCG.js → chunk-EGOWY342.js} +2 -2
  112. package/dist/chunk-EIB4FJVR.js +46 -0
  113. package/dist/chunk-EIB4FJVR.js.map +1 -0
  114. package/dist/{chunk-W44T2KHG.js → chunk-EWBDJQ5Y.js} +3 -3
  115. package/dist/{chunk-JMBTNVMW.js → chunk-FGRJJBFO.js} +2 -2
  116. package/dist/{chunk-F3TURDFG.js → chunk-FPB5LQWW.js} +4 -1
  117. package/dist/{chunk-F3TURDFG.js.map → chunk-FPB5LQWW.js.map} +1 -1
  118. package/dist/{chunk-OOBUWMPY.js → chunk-G2SJRFGP.js} +6 -6
  119. package/dist/{chunk-WGZHSQDV.js → chunk-G2XZFGYN.js} +4 -4
  120. package/dist/{chunk-JPNUKKSL.js → chunk-GGROFIYX.js} +2 -2
  121. package/dist/chunk-GXJSLNYO.js +74 -0
  122. package/dist/chunk-GXJSLNYO.js.map +1 -0
  123. package/dist/{chunk-VA5QRTZX.js → chunk-HG74GEVY.js} +2 -2
  124. package/dist/chunk-HMDYSGY6.js +54 -0
  125. package/dist/chunk-HMDYSGY6.js.map +1 -0
  126. package/dist/{chunk-WUUGE7QC.js → chunk-HS75MCQF.js} +4 -4
  127. package/dist/{chunk-DO6R3LIE.js → chunk-I6IJDTRP.js} +2 -2
  128. package/dist/{chunk-T3F2HWIG.js → chunk-IO7K7GES.js} +2 -2
  129. package/dist/{chunk-6II55MXS.js → chunk-JXLEQIJ7.js} +2 -2
  130. package/dist/{chunk-4XTSKGLX.js → chunk-JYXLW22X.js} +3 -3
  131. package/dist/chunk-LI4APB6M.js +218 -0
  132. package/dist/chunk-LI4APB6M.js.map +1 -0
  133. package/dist/{chunk-IFULZYYQ.js → chunk-LIAM7U2J.js} +2 -2
  134. package/dist/{chunk-LZAJONO5.js → chunk-LIDJWAQV.js} +2 -2
  135. package/dist/{chunk-B55FYF6F.js → chunk-LYMJ36UI.js} +2 -2
  136. package/dist/chunk-M4DB6ZNN.js +87 -0
  137. package/dist/chunk-M4DB6ZNN.js.map +1 -0
  138. package/dist/{chunk-5TKHJ5RW.js → chunk-MMQVWKFY.js} +17 -13
  139. package/dist/chunk-MMQVWKFY.js.map +1 -0
  140. package/dist/{chunk-IAT5WFEU.js → chunk-MNG536IS.js} +261 -797
  141. package/dist/chunk-MNG536IS.js.map +1 -0
  142. package/dist/{chunk-AOMUIF3R.js → chunk-MQT3WP3F.js} +2 -2
  143. package/dist/{chunk-F6AYWLRN.js → chunk-NE45P3OF.js} +2 -2
  144. package/dist/{chunk-5XTILJRI.js → chunk-NMA7RQPR.js} +2 -2
  145. package/dist/{chunk-46A4RGBC.js → chunk-OS4JVTHR.js} +3 -3
  146. package/dist/{chunk-W6YDAIVB.js → chunk-OSTXIFZW.js} +13 -2
  147. package/dist/chunk-OSTXIFZW.js.map +1 -0
  148. package/dist/chunk-P3YNEMYY.js +212 -0
  149. package/dist/chunk-P3YNEMYY.js.map +1 -0
  150. package/dist/{chunk-C3YEB7CR.js → chunk-PA67GXYJ.js} +5 -5
  151. package/dist/{chunk-NGAFYIHQ.js → chunk-PPJLJD2D.js} +2 -2
  152. package/dist/{chunk-AG6PANBG.js → chunk-PXJ6HE2W.js} +11 -11
  153. package/dist/{chunk-BOWAP64Q.js → chunk-QB4VXCFN.js} +2 -2
  154. package/dist/{chunk-L63M2PE4.js → chunk-QGAKUOKU.js} +2 -2
  155. package/dist/{chunk-T2ZNUWUY.js → chunk-QKFYJVDG.js} +2 -2
  156. package/dist/{chunk-YHSEUZV5.js → chunk-QLCMOHRE.js} +2 -2
  157. package/dist/{chunk-Q4AUIFUA.js → chunk-QMWKENNK.js} +4 -4
  158. package/dist/{chunk-UJXNBZYJ.js → chunk-R4JTUTU6.js} +12 -5
  159. package/dist/chunk-R4JTUTU6.js.map +1 -0
  160. package/dist/{chunk-TFS5FAAC.js → chunk-ROBGBT3D.js} +213 -77
  161. package/dist/chunk-ROBGBT3D.js.map +1 -0
  162. package/dist/{chunk-TNQR7N52.js → chunk-S3YM4SZQ.js} +2 -1
  163. package/dist/chunk-S3YM4SZQ.js.map +1 -0
  164. package/dist/{chunk-RW4QNB4J.js → chunk-S45INSV3.js} +3 -1
  165. package/dist/{chunk-RW4QNB4J.js.map → chunk-S45INSV3.js.map} +1 -1
  166. package/dist/{chunk-HVGCQMTQ.js → chunk-SJ7ZNUXB.js} +2 -2
  167. package/dist/{chunk-WCQ7L54B.js → chunk-SK6HEQTW.js} +2 -2
  168. package/dist/{chunk-PGAB2V53.js → chunk-SMBWBEE7.js} +2 -2
  169. package/dist/{chunk-SPN5YFXN.js → chunk-SS33RR4F.js} +8 -8
  170. package/dist/{chunk-NRFUYVW7.js → chunk-T3T5HTZZ.js} +2 -2
  171. package/dist/{chunk-KG2OOAFF.js → chunk-TQSCR5DU.js} +6 -6
  172. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  173. package/dist/{chunk-ZLVURGAJ.js → chunk-V2XNMIAM.js} +2 -2
  174. package/dist/{chunk-AS2NOPDM.js → chunk-V7IONNTJ.js} +2 -2
  175. package/dist/{chunk-OFBJD3V5.js → chunk-VV5GCNKG.js} +2 -2
  176. package/dist/{chunk-MDYZCPNQ.js → chunk-WL3PGPGU.js} +2 -2
  177. package/dist/{chunk-66YUOI53.js → chunk-WQW6KPVC.js} +1 -1
  178. package/dist/chunk-WQW6KPVC.js.map +1 -0
  179. package/dist/{chunk-2AV75BJW.js → chunk-WVI43D54.js} +24 -1
  180. package/dist/chunk-WVI43D54.js.map +1 -0
  181. package/dist/{chunk-N6I257OM.js → chunk-WYU66IVZ.js} +3 -3
  182. package/dist/{chunk-A7GQBJP5.js → chunk-X2NFFBTO.js} +4 -4
  183. package/dist/{chunk-D3DJYGU2.js → chunk-XEHLYA5Z.js} +3 -3
  184. package/dist/{chunk-JIWZVOQM.js → chunk-XKHRNAK7.js} +2 -2
  185. package/dist/{chunk-VW5TGNJN.js → chunk-XXLH6KFO.js} +2 -2
  186. package/dist/{chunk-WMTYEQO5.js → chunk-XZUHXKM3.js} +2 -2
  187. package/dist/{chunk-K4KE5MYE.js → chunk-Y5VT7BIT.js} +2 -2
  188. package/dist/{chunk-M7ECD3KN.js → chunk-YOSLKZLZ.js} +2 -2
  189. package/dist/{chunk-K75H7FSO.js → chunk-YXWMZAAN.js} +2 -2
  190. package/dist/{chunk-DSHSQGSN.js → chunk-ZEIJQ4I3.js} +2 -2
  191. package/dist/{cli-CZDhIcxu.d.ts → cli-B8YyIrPR.d.ts} +5 -5
  192. package/dist/cli.d.ts +17 -16
  193. package/dist/cli.js +81 -76
  194. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  195. package/dist/coding/export-okf-codegraph.js +12 -12
  196. package/dist/coding/pre-action-gate.d.ts +1 -1
  197. package/dist/compounding/engine.d.ts +2 -2
  198. package/dist/compounding/engine.js +13 -13
  199. package/dist/compounding/preference-consolidator.d.ts +1 -1
  200. package/dist/compression-optimizer.d.ts +1 -1
  201. package/dist/config.d.ts +1 -1
  202. package/dist/config.js +3 -2
  203. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  204. package/dist/connectors/codex-materialize-runner.js +13 -13
  205. package/dist/connectors/codex-materialize.d.ts +1 -1
  206. package/dist/connectors/index.d.ts +1 -1
  207. package/dist/connectors/index.js +13 -13
  208. package/dist/consolidation-provenance-check.d.ts +2 -2
  209. package/dist/consolidation-undo.d.ts +2 -2
  210. package/dist/contradiction/index.d.ts +4 -4
  211. package/dist/converge-config.d.ts +1 -1
  212. package/dist/convergence-refresh.d.ts +2 -2
  213. package/dist/convergence-refresh.js +15 -15
  214. package/dist/conversation-index/backend.d.ts +1 -1
  215. package/dist/conversation-index/chunker.d.ts +1 -1
  216. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  217. package/dist/conversation-index/indexer.d.ts +1 -1
  218. package/dist/conversation-index/search.d.ts +1 -1
  219. package/dist/corpus-watermark.d.ts +1 -1
  220. package/dist/corpus-watermark.js +15 -15
  221. package/dist/cross-lingual-recall.d.ts +1 -1
  222. package/dist/day-summary.d.ts +1 -1
  223. package/dist/deep-recall-http-glue.d.ts +15 -14
  224. package/dist/deep-recall-mcp-tools.d.ts +15 -14
  225. package/dist/deep-recall-policy-llm.d.ts +2 -2
  226. package/dist/deep-recall-seeds.d.ts +1 -1
  227. package/dist/deep-recall.js +2 -2
  228. package/dist/delinearize.d.ts +1 -1
  229. package/dist/dependency-propagation-config.d.ts +1 -1
  230. package/dist/{dependency-propagation-delivery-BXaUoVUf.d.ts → dependency-propagation-delivery-B-LvcDaq.d.ts} +1 -1
  231. package/dist/direct-answer-wiring.d.ts +1 -1
  232. package/dist/direct-answer.d.ts +1 -1
  233. package/dist/embedding-fallback.d.ts +1 -1
  234. package/dist/enrichment/index.d.ts +1 -1
  235. package/dist/entity-origin-fields.d.ts +1 -1
  236. package/dist/entity-retrieval.d.ts +2 -2
  237. package/dist/entity-retrieval.js +13 -13
  238. package/dist/entity-schema.d.ts +1 -1
  239. package/dist/episodic-context.d.ts +1 -1
  240. package/dist/eval-trajectory-contracts.d.ts +1 -1
  241. package/dist/eval-trajectory-store.d.ts +1 -1
  242. package/dist/eval-trajectory.d.ts +1 -1
  243. package/dist/explicit-capture.d.ts +11 -11
  244. package/dist/explicit-capture.js +2 -2
  245. package/dist/external-wiki-access.d.ts +15 -14
  246. package/dist/external-wiki-access.js +41 -40
  247. package/dist/external-wiki-collection-registration.d.ts +1 -1
  248. package/dist/external-wiki-collection.d.ts +1 -1
  249. package/dist/external-wiki-mcp-tools.d.ts +15 -14
  250. package/dist/extraction-error-classification.d.ts +1 -1
  251. package/dist/extraction-evidence-class.d.ts +142 -0
  252. package/dist/extraction-evidence-class.js +113 -0
  253. package/dist/extraction-evidence-class.js.map +1 -0
  254. package/dist/extraction-faithfulness.d.ts +2 -2
  255. package/dist/extraction-judge-telemetry.d.ts +2 -2
  256. package/dist/extraction-judge-training.d.ts +2 -2
  257. package/dist/extraction-judge.d.ts +2 -2
  258. package/dist/extraction-liveness.d.ts +1 -1
  259. package/dist/extraction-normalization.d.ts +1 -1
  260. package/dist/extraction-prompt.d.ts +1 -1
  261. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  262. package/dist/extraction-source-grounding.d.ts +1 -1
  263. package/dist/extraction-source-grounding.js +2 -2
  264. package/dist/extraction-span-config.d.ts +1 -1
  265. package/dist/extraction-span-materialize.d.ts +1 -1
  266. package/dist/extraction-span-wire.d.ts +1 -1
  267. package/dist/extraction.d.ts +2 -2
  268. package/dist/extraction.js +21 -21
  269. package/dist/fallback-llm-codex-subscription.d.ts +1 -1
  270. package/dist/fallback-llm.d.ts +1 -1
  271. package/dist/{generic-recall-paths-BkVVEoeO.d.ts → generic-recall-paths-Bfc7zigS.d.ts} +1 -1
  272. package/dist/graph-append-error.d.ts +1 -1
  273. package/dist/graph-dashboard-diff.d.ts +1 -1
  274. package/dist/graph-dashboard-key.d.ts +1 -1
  275. package/dist/graph-dashboard-parser.d.ts +1 -1
  276. package/dist/graph-edge-reinforcement.d.ts +1 -1
  277. package/dist/graph-jsonl.d.ts +1 -1
  278. package/dist/graph-path-reconstruction.d.ts +1 -1
  279. package/dist/graph-path-scoring.d.ts +1 -1
  280. package/dist/graph-snapshot.d.ts +1 -1
  281. package/dist/graph.d.ts +1 -1
  282. package/dist/harmonic-retrieval.js +1 -1
  283. package/dist/importance.d.ts +1 -1
  284. package/dist/importers/index.d.ts +1 -1
  285. package/dist/importers/test-utils.d.ts +1 -1
  286. package/dist/in-flight-reads.d.ts +1 -1
  287. package/dist/{index-TBPe6NvB.d.ts → index-C7IA1DxB.d.ts} +3 -3
  288. package/dist/index.d.ts +121 -30
  289. package/dist/index.js +170 -123
  290. package/dist/intent.d.ts +1 -1
  291. package/dist/lcm/engine.d.ts +1 -1
  292. package/dist/lcm/engine.js +2 -2
  293. package/dist/lcm/index.d.ts +1 -1
  294. package/dist/lcm/index.js +4 -4
  295. package/dist/lcm/tools.d.ts +1 -1
  296. package/dist/lifecycle.d.ts +1 -1
  297. package/dist/live-connectors-runner.d.ts +1 -1
  298. package/dist/{local-llm-DdrhmecM.d.ts → local-llm-DH4tWtck.d.ts} +1 -1
  299. package/dist/local-llm-helpers.d.ts +2 -2
  300. package/dist/local-llm.d.ts +2 -2
  301. package/dist/local-llm.js +2 -2
  302. package/dist/local-model-endpoint.d.ts +1 -1
  303. package/dist/location/index.d.ts +5 -5
  304. package/dist/location/index.js +15 -15
  305. package/dist/maintenance/memory-governance.d.ts +1 -1
  306. package/dist/maintenance/memory-governance.js +13 -13
  307. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  308. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +13 -13
  309. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  310. package/dist/maintenance/rebuild-memory-projection.js +14 -14
  311. package/dist/{maintenance-B813YFWJ.d.ts → maintenance-n6yeTQhR.d.ts} +4 -4
  312. package/dist/mcp-memory-inspector-app.d.ts +15 -14
  313. package/dist/mcp-read-only-tools.js +1 -1
  314. package/dist/memory-action-policy.d.ts +1 -1
  315. package/dist/memory-age.d.ts +100 -0
  316. package/dist/memory-age.js +22 -0
  317. package/dist/memory-age.js.map +1 -0
  318. package/dist/memory-browse-http-glue.d.ts +170 -0
  319. package/dist/memory-browse-http-glue.js +9 -0
  320. package/dist/memory-browse-http-glue.js.map +1 -0
  321. package/dist/memory-browse-mcp-tools.d.ts +160 -0
  322. package/dist/memory-browse-mcp-tools.js +8 -0
  323. package/dist/memory-browse-mcp-tools.js.map +1 -0
  324. package/dist/memory-browse-operations.d.ts +2 -0
  325. package/dist/memory-browse-operations.js +246 -0
  326. package/dist/memory-browse-operations.js.map +1 -0
  327. package/dist/memory-browse.d.ts +113 -0
  328. package/dist/memory-browse.js +49 -0
  329. package/dist/memory-browse.js.map +1 -0
  330. package/dist/memory-cache.d.ts +1 -1
  331. package/dist/memory-controller.d.ts +1 -1
  332. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  333. package/dist/memory-projection-store.d.ts +1 -1
  334. package/dist/memory-provenance.d.ts +1 -1
  335. package/dist/memory-snapshot.d.ts +1 -1
  336. package/dist/memory-subject-cli.d.ts +15 -14
  337. package/dist/memory-subject.d.ts +15 -14
  338. package/dist/memory-worth-outcomes.d.ts +2 -2
  339. package/dist/models-json.d.ts +1 -1
  340. package/dist/namespaces/migrate.d.ts +3 -3
  341. package/dist/namespaces/migrate.js +14 -14
  342. package/dist/namespaces/principal.d.ts +1 -1
  343. package/dist/namespaces/search.d.ts +1 -1
  344. package/dist/namespaces/search.js +6 -6
  345. package/dist/namespaces/storage.d.ts +3 -3
  346. package/dist/namespaces/storage.js +13 -13
  347. package/dist/native-knowledge.d.ts +1 -1
  348. package/dist/offline-sync-impression-drain.d.ts +1 -1
  349. package/dist/operator-doctor-corpus.d.ts +1 -1
  350. package/dist/operator-doctor-corpus.js +16 -16
  351. package/dist/operator-doctor-replica.d.ts +1 -1
  352. package/dist/operator-toolkit.d.ts +3 -3
  353. package/dist/operator-toolkit.js +23 -22
  354. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  355. package/dist/orchestration/maintenance.d.ts +4 -4
  356. package/dist/orchestration/maintenance.js +23 -23
  357. package/dist/{orchestrator-BCvQavIS.d.ts → orchestrator-Cirjo3ZB.d.ts} +10 -10
  358. package/dist/orchestrator.d.ts +11 -11
  359. package/dist/orchestrator.js +112 -106
  360. package/dist/patterns-cli.d.ts +1 -1
  361. package/dist/{pipeline-4lqKJZ_0.d.ts → pipeline-DK79FrgH.d.ts} +1 -1
  362. package/dist/policy-runtime.d.ts +1 -1
  363. package/dist/proactive-contention.d.ts +2 -2
  364. package/dist/provenance.d.ts +77 -2
  365. package/dist/provenance.js +7 -3
  366. package/dist/{public-http-NH72a6aa.d.ts → public-http-VB85y0ZH.d.ts} +1 -1
  367. package/dist/{qmd-DnoWaXKb.d.ts → qmd-BT0ErlRS.d.ts} +1 -1
  368. package/dist/qmd-preflight.d.ts +2 -2
  369. package/dist/qmd-recall-cache.d.ts +1 -1
  370. package/dist/qmd.d.ts +2 -2
  371. package/dist/qmd.js +4 -4
  372. package/dist/recall-concurrency-config.d.ts +1 -1
  373. package/dist/recall-disclosure-escalation.d.ts +1 -1
  374. package/dist/recall-explain-renderer.d.ts +1 -1
  375. package/dist/recall-explain-renderer.js +3 -3
  376. package/dist/recall-memory-map.d.ts +1 -1
  377. package/dist/recall-navigate-access.d.ts +1 -1
  378. package/dist/recall-navigate-access.js +2 -2
  379. package/dist/recall-navigate-disclosure.d.ts +1 -1
  380. package/dist/recall-navigate-disclosure.js +2 -2
  381. package/dist/recall-navigate.d.ts +1 -1
  382. package/dist/recall-navigate.js +2 -2
  383. package/dist/recall-navigation-http-glue.d.ts +15 -14
  384. package/dist/recall-navigation-mcp-tools.d.ts +15 -14
  385. package/dist/recall-navigation-operations.js +41 -40
  386. package/dist/recall-navigation-renderer.d.ts +1 -1
  387. package/dist/recall-navigation.d.ts +1 -1
  388. package/dist/recall-navigation.js +40 -39
  389. package/dist/recall-planner-llm.d.ts +1 -1
  390. package/dist/recall-state-view-admission.d.ts +2 -2
  391. package/dist/recall-state-view-admission.js +5 -5
  392. package/dist/recall-state-view-anchors.d.ts +1 -1
  393. package/dist/recall-state.d.ts +1 -1
  394. package/dist/recall-tag-filter.d.ts +1 -1
  395. package/dist/recall-timings.d.ts +1 -1
  396. package/dist/recall-xray-cli.d.ts +1 -1
  397. package/dist/recall-xray-cli.js +4 -4
  398. package/dist/recall-xray-renderer.d.ts +1 -1
  399. package/dist/recall-xray-renderer.js +3 -3
  400. package/dist/recall-xray.d.ts +1 -1
  401. package/dist/recall-xray.js +2 -2
  402. package/dist/reconcile/cursor.d.ts +1 -1
  403. package/dist/reconcile/manifest.d.ts +4 -1
  404. package/dist/reconcile/manifest.js +1 -1
  405. package/dist/reconcile/plan.d.ts +1 -1
  406. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  407. package/dist/replay/normalizers/claude.d.ts +1 -1
  408. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  409. package/dist/replay/normalizers/shared.d.ts +1 -1
  410. package/dist/replay/runner.d.ts +1 -1
  411. package/dist/replay/types.d.ts +1 -1
  412. package/dist/replica-divergence.d.ts +1 -1
  413. package/dist/replica-peers-config.d.ts +1 -1
  414. package/dist/resolve-auth-token.d.ts +1 -1
  415. package/dist/resume-bundles.js +4 -3
  416. package/dist/retrieval-agents.d.ts +2 -2
  417. package/dist/retrieval-tiers.d.ts +1 -1
  418. package/dist/routing/engine.d.ts +1 -1
  419. package/dist/routing/store.d.ts +1 -1
  420. package/dist/salvage-envelope.d.ts +1 -1
  421. package/dist/{scope-profiles-crazXegZ.d.ts → scope-profiles-BgPQx9iE.d.ts} +1 -1
  422. package/dist/search/embed-helper.d.ts +1 -1
  423. package/dist/search/factory.d.ts +1 -1
  424. package/dist/search/factory.js +5 -5
  425. package/dist/search/index.d.ts +1 -1
  426. package/dist/search/index.js +9 -9
  427. package/dist/search/lancedb-backend.d.ts +1 -1
  428. package/dist/search/meilisearch-backend.d.ts +1 -1
  429. package/dist/search/noop-backend.d.ts +1 -1
  430. package/dist/search/orama-backend.d.ts +1 -1
  431. package/dist/search/port.d.ts +1 -1
  432. package/dist/search/remote-backend.d.ts +1 -1
  433. package/dist/{semantic-consolidation-B09JI9WM.d.ts → semantic-consolidation-BrAWKVcm.d.ts} +1 -1
  434. package/dist/semantic-consolidation.d.ts +2 -2
  435. package/dist/semantic-consolidation.js +14 -14
  436. package/dist/semantic-rule-promotion.js +13 -13
  437. package/dist/semantic-rule-verifier.d.ts +1 -1
  438. package/dist/semantic-rule-verifier.js +13 -13
  439. package/dist/{service-Echc5Xso.d.ts → service-CqHOTg87.d.ts} +2 -2
  440. package/dist/session-observer-bands.d.ts +1 -1
  441. package/dist/session-observer-state.d.ts +1 -1
  442. package/dist/shared-context/manager.d.ts +1 -1
  443. package/dist/signal.d.ts +1 -1
  444. package/dist/source-agent-qualifier.d.ts +1 -1
  445. package/dist/source-agent-qualifier.js +17 -17
  446. package/dist/standing-memory-block.d.ts +77 -0
  447. package/dist/standing-memory-block.js +40 -0
  448. package/dist/standing-memory-block.js.map +1 -0
  449. package/dist/standup/build.js +13 -13
  450. package/dist/{storage-ClkHCQSE.d.ts → storage-mD2YQ8_2.d.ts} +17 -3
  451. package/dist/storage.d.ts +2 -2
  452. package/dist/storage.js +12 -12
  453. package/dist/subject-config.d.ts +1 -1
  454. package/dist/summarizer.d.ts +1 -1
  455. package/dist/summarizer.js +3 -3
  456. package/dist/summary-snapshot.d.ts +1 -1
  457. package/dist/support-passport/index.d.ts +18 -17
  458. package/dist/support-passport/index.js +43 -42
  459. package/dist/{tagging-ksktJ60G.d.ts → tagging-CiAVA-ID.d.ts} +2 -2
  460. package/dist/temporal-supersession.d.ts +2 -2
  461. package/dist/temporal-timeline-recall.d.ts +1 -1
  462. package/dist/temporal-validity.d.ts +1 -1
  463. package/dist/threading.d.ts +1 -1
  464. package/dist/tier-migration.d.ts +2 -2
  465. package/dist/tier-routing.d.ts +1 -1
  466. package/dist/topics.d.ts +1 -1
  467. package/dist/transcript.d.ts +1 -1
  468. package/dist/transfer/export-okf.d.ts +1 -1
  469. package/dist/transfer/export-okf.js +13 -13
  470. package/dist/trust-score-stage.d.ts +1 -1
  471. package/dist/trust-score.d.ts +1 -1
  472. package/dist/{types-nmhnJpxx.d.ts → types-DgDaoY61.d.ts} +6 -0
  473. package/dist/types.d.ts +1 -1
  474. package/dist/types.js +1 -1
  475. package/dist/utility-runtime.d.ts +1 -1
  476. package/dist/verified-recall.js +13 -13
  477. package/dist/who-knows-cli.d.ts +15 -14
  478. package/dist/who-knows-cli.js +14 -14
  479. package/dist/who-knows.d.ts +15 -14
  480. package/dist/who-knows.js +13 -13
  481. package/dist/write-envelope.d.ts +1 -1
  482. package/package.json +2 -2
  483. package/src/access-boundary.ts +3 -0
  484. package/src/access-http.ts +2 -2
  485. package/src/access-mcp-output-schemas.ts +25 -0
  486. package/src/access-mcp.ts +3 -3
  487. package/src/access-operations.ts +2 -0
  488. package/src/access-service.ts +6 -1
  489. package/src/access-surface-catalog.test.ts +20 -0
  490. package/src/access-surface-catalog.ts +6 -0
  491. package/src/activity/timeline/index.ts +1 -0
  492. package/src/activity/timeline/journal-recap.test.ts +17 -0
  493. package/src/activity/timeline/journal-recap.ts +19 -6
  494. package/src/activity/timeline/recap-export-range.test.ts +289 -0
  495. package/src/activity/timeline/recap-export-range.ts +169 -0
  496. package/src/activity/timeline/recap-export.test.ts +73 -1
  497. package/src/activity/timeline/recap-export.ts +57 -4
  498. package/src/cli/memory-browse-commands.ts +77 -0
  499. package/src/cli.ts +2 -2
  500. package/src/config.ts +11 -0
  501. package/src/dedup/merge.test.ts +185 -8
  502. package/src/extraction-evidence-class.test.ts +355 -0
  503. package/src/extraction-evidence-class.ts +241 -0
  504. package/src/index.ts +1 -0
  505. package/src/mcp-read-only-tools.ts +3 -0
  506. package/src/memory-age.test.ts +106 -0
  507. package/src/memory-age.ts +196 -0
  508. package/src/memory-browse-http-glue.ts +93 -0
  509. package/src/memory-browse-mcp-tools.ts +57 -0
  510. package/src/memory-browse-operations.ts +88 -0
  511. package/src/memory-browse-surface.test.ts +500 -0
  512. package/src/memory-browse.ts +316 -0
  513. package/src/orchestration/recall-search-pipeline.test.ts +207 -1
  514. package/src/orchestration/recall-search-pipeline.ts +13 -9
  515. package/src/orchestration/semantic-merge-commit-effects.ts +31 -9
  516. package/src/orchestration/semantic-merge-persist.ts +16 -5
  517. package/src/provenance.ts +3 -3
  518. package/src/reconcile/manifest.test.ts +27 -0
  519. package/src/reconcile/manifest.ts +7 -0
  520. package/src/standing-memory-block.test.ts +262 -0
  521. package/src/standing-memory-block.ts +331 -0
  522. package/src/storage/cas-revision-host.ts +22 -0
  523. package/src/storage/cas-revision-store.test.ts +44 -1
  524. package/src/storage/cas-revision-store.ts +23 -0
  525. package/src/storage/tombstone-blocked-capture-sync.ts +26 -1
  526. package/src/storage-frontmatter-cas.test.ts +49 -1
  527. package/src/storage.ts +1 -1
  528. package/src/types.ts +6 -0
  529. package/dist/chunk-2AV75BJW.js.map +0 -1
  530. package/dist/chunk-5TKHJ5RW.js.map +0 -1
  531. package/dist/chunk-66YUOI53.js.map +0 -1
  532. package/dist/chunk-7LKXP4QG.js.map +0 -1
  533. package/dist/chunk-IAT5WFEU.js.map +0 -1
  534. package/dist/chunk-NKDQXDFL.js.map +0 -1
  535. package/dist/chunk-OREGA7GY.js.map +0 -1
  536. package/dist/chunk-SHEHQBCG.js.map +0 -1
  537. package/dist/chunk-TFS5FAAC.js.map +0 -1
  538. package/dist/chunk-TNQR7N52.js.map +0 -1
  539. package/dist/chunk-UJXNBZYJ.js.map +0 -1
  540. package/dist/chunk-W6YDAIVB.js.map +0 -1
  541. /package/dist/{chunk-C3MCMFNV.js.map → chunk-2QX65IEC.js.map} +0 -0
  542. /package/dist/{chunk-HBGSZ62Z.js.map → chunk-3RKVSECD.js.map} +0 -0
  543. /package/dist/{chunk-R4HFCATE.js.map → chunk-4LPIVP77.js.map} +0 -0
  544. /package/dist/{chunk-PW4HTWXL.js.map → chunk-55XWRL6F.js.map} +0 -0
  545. /package/dist/{chunk-E5VOKZQV.js.map → chunk-5KBI2MOC.js.map} +0 -0
  546. /package/dist/{chunk-ZQ533JDE.js.map → chunk-6A6HSXWV.js.map} +0 -0
  547. /package/dist/{chunk-4HTQ76O4.js.map → chunk-7SJCSDQ3.js.map} +0 -0
  548. /package/dist/{chunk-A2YN3FR4.js.map → chunk-7YUX52XZ.js.map} +0 -0
  549. /package/dist/{chunk-LQVXSRAJ.js.map → chunk-B4EGAHHS.js.map} +0 -0
  550. /package/dist/{chunk-EUP4AXIW.js.map → chunk-B6VDWDFN.js.map} +0 -0
  551. /package/dist/{chunk-Z5YNVWRD.js.map → chunk-BMENHAJL.js.map} +0 -0
  552. /package/dist/{chunk-5ZXGH2ZL.js.map → chunk-BXOPUJ3W.js.map} +0 -0
  553. /package/dist/{chunk-J6NEOCQC.js.map → chunk-CD7VTZIG.js.map} +0 -0
  554. /package/dist/{chunk-EC5SVM6H.js.map → chunk-DE4ZGH2N.js.map} +0 -0
  555. /package/dist/{chunk-2LRO73MN.js.map → chunk-DRLZB3CN.js.map} +0 -0
  556. /package/dist/{chunk-Q4MI2KCG.js.map → chunk-EGOWY342.js.map} +0 -0
  557. /package/dist/{chunk-W44T2KHG.js.map → chunk-EWBDJQ5Y.js.map} +0 -0
  558. /package/dist/{chunk-JMBTNVMW.js.map → chunk-FGRJJBFO.js.map} +0 -0
  559. /package/dist/{chunk-OOBUWMPY.js.map → chunk-G2SJRFGP.js.map} +0 -0
  560. /package/dist/{chunk-WGZHSQDV.js.map → chunk-G2XZFGYN.js.map} +0 -0
  561. /package/dist/{chunk-JPNUKKSL.js.map → chunk-GGROFIYX.js.map} +0 -0
  562. /package/dist/{chunk-VA5QRTZX.js.map → chunk-HG74GEVY.js.map} +0 -0
  563. /package/dist/{chunk-WUUGE7QC.js.map → chunk-HS75MCQF.js.map} +0 -0
  564. /package/dist/{chunk-DO6R3LIE.js.map → chunk-I6IJDTRP.js.map} +0 -0
  565. /package/dist/{chunk-T3F2HWIG.js.map → chunk-IO7K7GES.js.map} +0 -0
  566. /package/dist/{chunk-6II55MXS.js.map → chunk-JXLEQIJ7.js.map} +0 -0
  567. /package/dist/{chunk-4XTSKGLX.js.map → chunk-JYXLW22X.js.map} +0 -0
  568. /package/dist/{chunk-IFULZYYQ.js.map → chunk-LIAM7U2J.js.map} +0 -0
  569. /package/dist/{chunk-LZAJONO5.js.map → chunk-LIDJWAQV.js.map} +0 -0
  570. /package/dist/{chunk-B55FYF6F.js.map → chunk-LYMJ36UI.js.map} +0 -0
  571. /package/dist/{chunk-AOMUIF3R.js.map → chunk-MQT3WP3F.js.map} +0 -0
  572. /package/dist/{chunk-F6AYWLRN.js.map → chunk-NE45P3OF.js.map} +0 -0
  573. /package/dist/{chunk-5XTILJRI.js.map → chunk-NMA7RQPR.js.map} +0 -0
  574. /package/dist/{chunk-46A4RGBC.js.map → chunk-OS4JVTHR.js.map} +0 -0
  575. /package/dist/{chunk-C3YEB7CR.js.map → chunk-PA67GXYJ.js.map} +0 -0
  576. /package/dist/{chunk-NGAFYIHQ.js.map → chunk-PPJLJD2D.js.map} +0 -0
  577. /package/dist/{chunk-AG6PANBG.js.map → chunk-PXJ6HE2W.js.map} +0 -0
  578. /package/dist/{chunk-BOWAP64Q.js.map → chunk-QB4VXCFN.js.map} +0 -0
  579. /package/dist/{chunk-L63M2PE4.js.map → chunk-QGAKUOKU.js.map} +0 -0
  580. /package/dist/{chunk-T2ZNUWUY.js.map → chunk-QKFYJVDG.js.map} +0 -0
  581. /package/dist/{chunk-YHSEUZV5.js.map → chunk-QLCMOHRE.js.map} +0 -0
  582. /package/dist/{chunk-Q4AUIFUA.js.map → chunk-QMWKENNK.js.map} +0 -0
  583. /package/dist/{chunk-HVGCQMTQ.js.map → chunk-SJ7ZNUXB.js.map} +0 -0
  584. /package/dist/{chunk-WCQ7L54B.js.map → chunk-SK6HEQTW.js.map} +0 -0
  585. /package/dist/{chunk-PGAB2V53.js.map → chunk-SMBWBEE7.js.map} +0 -0
  586. /package/dist/{chunk-SPN5YFXN.js.map → chunk-SS33RR4F.js.map} +0 -0
  587. /package/dist/{chunk-NRFUYVW7.js.map → chunk-T3T5HTZZ.js.map} +0 -0
  588. /package/dist/{chunk-KG2OOAFF.js.map → chunk-TQSCR5DU.js.map} +0 -0
  589. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  590. /package/dist/{chunk-ZLVURGAJ.js.map → chunk-V2XNMIAM.js.map} +0 -0
  591. /package/dist/{chunk-AS2NOPDM.js.map → chunk-V7IONNTJ.js.map} +0 -0
  592. /package/dist/{chunk-OFBJD3V5.js.map → chunk-VV5GCNKG.js.map} +0 -0
  593. /package/dist/{chunk-MDYZCPNQ.js.map → chunk-WL3PGPGU.js.map} +0 -0
  594. /package/dist/{chunk-N6I257OM.js.map → chunk-WYU66IVZ.js.map} +0 -0
  595. /package/dist/{chunk-A7GQBJP5.js.map → chunk-X2NFFBTO.js.map} +0 -0
  596. /package/dist/{chunk-D3DJYGU2.js.map → chunk-XEHLYA5Z.js.map} +0 -0
  597. /package/dist/{chunk-JIWZVOQM.js.map → chunk-XKHRNAK7.js.map} +0 -0
  598. /package/dist/{chunk-VW5TGNJN.js.map → chunk-XXLH6KFO.js.map} +0 -0
  599. /package/dist/{chunk-WMTYEQO5.js.map → chunk-XZUHXKM3.js.map} +0 -0
  600. /package/dist/{chunk-K4KE5MYE.js.map → chunk-Y5VT7BIT.js.map} +0 -0
  601. /package/dist/{chunk-M7ECD3KN.js.map → chunk-YOSLKZLZ.js.map} +0 -0
  602. /package/dist/{chunk-K75H7FSO.js.map → chunk-YXWMZAAN.js.map} +0 -0
  603. /package/dist/{chunk-DSHSQGSN.js.map → chunk-ZEIJQ4I3.js.map} +0 -0
@@ -475,11 +475,586 @@ var DeletionRevisionStore = class {
475
475
  }
476
476
  };
477
477
 
478
+ // src/storage/cas-revision-store.ts
479
+ import { createHash as createHash2, randomUUID as randomUUID2 } from "crypto";
480
+ import { mkdir as mkdir2, open as open2, readFile as readFile2, rename as rename2, unlink as unlink2 } from "fs/promises";
481
+ import path2 from "path";
482
+ var ACCESS_TELEMETRY_FRONTMATTER_KEY = /^(?:accessCount|lastAccessed):/;
483
+ function canonicalSemanticFileText(raw) {
484
+ const lines = raw.split("\n");
485
+ if (lines[0] !== "---") return raw;
486
+ const closing = lines.indexOf("---", 1);
487
+ if (closing === -1) return raw;
488
+ const frontmatter = lines.slice(1, closing).filter((line) => !ACCESS_TELEMETRY_FRONTMATTER_KEY.test(line));
489
+ return [...lines.slice(0, 1), ...frontmatter, ...lines.slice(closing)].join("\n");
490
+ }
491
+ var CAS_REVISION_LOCK_STALE_MS = 6e4;
492
+ var CAS_REVISION_LOCK_MAX_WAIT_MS = 12e4;
493
+ var SHA256_HEX = /^[0-9a-f]{64}$/;
494
+ function isDigestOrNullOrUndefined(value) {
495
+ if (value === void 0 || value === null) return true;
496
+ return typeof value === "string" && SHA256_HEX.test(value);
497
+ }
498
+ function pendingWriteHasLanded(view) {
499
+ if (view.writeLanded === true) return true;
500
+ if (view.writeLanded === false) return false;
501
+ return view.expectedDigest !== void 0;
502
+ }
503
+ var CasRevisionStore = class {
504
+ baseDir;
505
+ legacyMetadataPath;
506
+ constructor(baseDir) {
507
+ this.baseDir = baseDir;
508
+ this.legacyMetadataPath = path2.join(baseDir, ".offline-sync", "cas-revisions.v1.json");
509
+ }
510
+ parseCasRevisionMetadata(raw) {
511
+ let parsed;
512
+ try {
513
+ parsed = JSON.parse(raw);
514
+ } catch {
515
+ throw new Error("CAS revision metadata is invalid.");
516
+ }
517
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
518
+ throw new Error("CAS revision metadata is invalid.");
519
+ }
520
+ const root = parsed;
521
+ if (Object.keys(root).sort().join(",") !== "revisions,version" || root.version !== 1 || !Array.isArray(root.revisions)) {
522
+ throw new Error("CAS revision metadata is invalid.");
523
+ }
524
+ const revisions = /* @__PURE__ */ new Map();
525
+ for (const rawEntry of root.revisions) {
526
+ if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) {
527
+ throw new Error("CAS revision metadata is invalid.");
528
+ }
529
+ const entry = rawEntry;
530
+ if (Object.keys(entry).sort().join(",") !== "path,revision" || typeof entry.path !== "string" || !isValidManagedStoragePath(entry.path) || typeof entry.revision !== "string" || entry.revision.length === 0 || revisions.has(entry.path)) {
531
+ throw new Error("CAS revision metadata is invalid.");
532
+ }
533
+ revisions.set(entry.path, entry.revision);
534
+ }
535
+ return revisions;
536
+ }
537
+ async readLegacyMetadata() {
538
+ const baseDir = path2.resolve(this.baseDir);
539
+ const legacyPath = await resolveSafeStoragePath(baseDir, path2.relative(baseDir, this.legacyMetadataPath));
540
+ let raw;
541
+ try {
542
+ raw = await readFile2(legacyPath, "utf8");
543
+ } catch (error) {
544
+ if (isErrnoCode(error, "ENOENT")) return /* @__PURE__ */ new Map();
545
+ throw new Error("CAS revision metadata is unavailable.");
546
+ }
547
+ return this.parseCasRevisionMetadata(raw);
548
+ }
549
+ /** #2813 (P1 A): every sidecar path is resolved (and symlink-audited)
550
+ * inside the memory root before it is used for a lock, read, rename, or
551
+ * unlink. A symlinked `.offline-sync`, `.offline-sync/cas-revisions`, or
552
+ * shard file makes this throw, so no sidecar traffic can follow a link
553
+ * out of the root. */
554
+ async getSafeShardInfo(relativePath) {
555
+ const baseDir = path2.resolve(this.baseDir);
556
+ const hash = createHash2("sha256").update(relativePath).digest("hex");
557
+ const shardPath = await resolveSafeStoragePath(baseDir, ".offline-sync", "cas-revisions", `${hash}.json`);
558
+ const lockPath = await resolveSafeStoragePath(baseDir, ".offline-sync", "cas-revisions", `${hash}.json.lock`);
559
+ return { shardPath, lockPath };
560
+ }
561
+ async readShardView(shardPath, relativePath) {
562
+ let raw;
563
+ try {
564
+ raw = await readFile2(shardPath, "utf8");
565
+ } catch (error) {
566
+ if (isErrnoCode(error, "ENOENT")) return { kind: "missing" };
567
+ throw error;
568
+ }
569
+ let parsed;
570
+ try {
571
+ parsed = JSON.parse(raw);
572
+ } catch {
573
+ throw new Error("CAS revision shard is unreadable.");
574
+ }
575
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
576
+ return { kind: "foreign" };
577
+ }
578
+ const root = parsed;
579
+ if (root.state !== void 0) {
580
+ if (root.version !== 1 || typeof root.path !== "string" || typeof root.revision !== "string" || root.revision.length === 0 || root.state !== "pending" && root.state !== "committed" || root.previous !== void 0 && (typeof root.previous !== "string" || root.previous.length === 0) || !isDigestOrNullOrUndefined(root.baselineDigest) || !isDigestOrNullOrUndefined(root.expectedDigest) || root.writeLanded !== void 0 && typeof root.writeLanded !== "boolean") {
581
+ throw new Error("CAS revision shard is unreadable.");
582
+ }
583
+ const foreign = root.path !== relativePath;
584
+ const committedDigest = typeof root.committedDigest === "string" ? root.committedDigest : void 0;
585
+ const committedSemanticFingerprint = typeof root.committedSemanticFingerprint === "string" ? root.committedSemanticFingerprint : void 0;
586
+ return root.state === "pending" ? {
587
+ kind: "pending",
588
+ revision: root.revision,
589
+ previous: root.previous,
590
+ foreign,
591
+ baselineDigest: root.baselineDigest,
592
+ expectedDigest: root.expectedDigest,
593
+ ...typeof root.writeLanded === "boolean" ? { writeLanded: root.writeLanded } : {}
594
+ } : {
595
+ kind: "committed",
596
+ revision: root.revision,
597
+ committedDigest,
598
+ committedSemanticFingerprint,
599
+ foreign
600
+ };
601
+ }
602
+ if (root.version === 1 && root.path === relativePath && typeof root.revision === "string" && root.revision.length > 0) {
603
+ const committedDigest = typeof root.committedDigest === "string" ? root.committedDigest : void 0;
604
+ const committedSemanticFingerprint = typeof root.committedSemanticFingerprint === "string" ? root.committedSemanticFingerprint : void 0;
605
+ return {
606
+ kind: "committed",
607
+ revision: root.revision,
608
+ committedDigest,
609
+ committedSemanticFingerprint,
610
+ foreign: false
611
+ };
612
+ }
613
+ return { kind: "foreign" };
614
+ }
615
+ async readStandingRevision(relativePath) {
616
+ try {
617
+ return await this.readStandingRevisionStrict(relativePath);
618
+ } catch (error) {
619
+ log.warn(`CasRevisionStore failed to read standing revision for ${relativePath}: ${error}`);
620
+ return void 0;
621
+ }
622
+ }
623
+ /** #2813 (P1 A): strict core of {@link readStandingRevision}. Returns
624
+ * undefined ONLY when no receipt exists for the target — the shard is
625
+ * absent (or names another target) and the legacy metadata holds no
626
+ * entry. THROWS when the standing receipt cannot be determined: an
627
+ * unreadable or corrupt shard, a PENDING reservation awaiting
628
+ * finalization or recovery, or unreadable or invalid legacy metadata.
629
+ * Fail-open callers collapse the throw into undefined; truthful callers
630
+ * ({@link readRevisionStatus}) report `unavailable` so a transaction can
631
+ * refuse instead of mistaking the failure for absence. */
632
+ async readStandingRevisionStrict(relativePath) {
633
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
634
+ const view = await this.readShardView(shardPath, relativePath);
635
+ if (view.kind === "pending") {
636
+ throw new Error(
637
+ `CAS revision receipt for ${relativePath} is pending finalization (recovery needed).`
638
+ );
639
+ }
640
+ if (view.kind === "committed" && !view.foreign) {
641
+ return {
642
+ revision: view.revision,
643
+ committedDigest: view.committedDigest,
644
+ committedSemanticFingerprint: view.committedSemanticFingerprint
645
+ };
646
+ }
647
+ const legacyMap = await this.readLegacyMetadata();
648
+ const legacyRev = legacyMap.get(relativePath);
649
+ return legacyRev === void 0 ? void 0 : { revision: legacyRev };
650
+ }
651
+ async writeShard(shardPath, relativePath, revision, lock, state, previous, evidence) {
652
+ let payload;
653
+ if (state === "committed") {
654
+ payload = { version: 1, path: relativePath, revision, state };
655
+ if (evidence?.committedDigest !== void 0) {
656
+ payload.committedDigest = evidence.committedDigest;
657
+ }
658
+ if (evidence?.committedSemanticFingerprint !== void 0) {
659
+ payload.committedSemanticFingerprint = evidence.committedSemanticFingerprint;
660
+ }
661
+ } else {
662
+ payload = { version: 1, path: relativePath, revision, state };
663
+ if (previous !== void 0) payload.previous = previous;
664
+ if (evidence !== void 0) {
665
+ if (evidence.baselineDigest !== void 0) payload.baselineDigest = evidence.baselineDigest;
666
+ if (evidence.expectedDigest !== void 0) payload.expectedDigest = evidence.expectedDigest;
667
+ if (evidence.writeLanded !== void 0) payload.writeLanded = evidence.writeLanded;
668
+ }
669
+ }
670
+ const baseDir = path2.resolve(this.baseDir);
671
+ const temporaryPath = await resolveSafeStoragePath(
672
+ baseDir,
673
+ path2.relative(baseDir, `${shardPath}.${process.pid}.${randomUUID2()}.tmp`)
674
+ );
675
+ let handle = null;
676
+ try {
677
+ await mkdir2(path2.dirname(shardPath), { recursive: true });
678
+ handle = await open2(temporaryPath, "wx", 384);
679
+ await handle.writeFile(`${JSON.stringify(payload)}
680
+ `, "utf8");
681
+ await handle.sync();
682
+ await handle.close();
683
+ handle = null;
684
+ if (!await lock.refresh()) {
685
+ throw new Error("CAS revision shard lock was lost.");
686
+ }
687
+ await rename2(temporaryPath, shardPath);
688
+ } finally {
689
+ if (handle !== null) {
690
+ await handle.close().catch((error) => {
691
+ log.warn("failed to close CAS revision shard temporary file", error);
692
+ });
693
+ }
694
+ await unlink2(temporaryPath).catch((error) => {
695
+ if (!isErrnoCode(error, "ENOENT")) {
696
+ log.warn("failed to clean up CAS revision shard temporary file", error);
697
+ }
698
+ });
699
+ }
700
+ }
701
+ async resolveRelativePath(filePath) {
702
+ const baseDir = path2.resolve(this.baseDir);
703
+ const target = await resolveSafeStoragePath(baseDir, path2.relative(baseDir, path2.resolve(baseDir, filePath)));
704
+ return path2.relative(baseDir, target).split(path2.sep).join("/");
705
+ }
706
+ async withShardLock(relativePath, task) {
707
+ const { lockPath } = await this.getSafeShardInfo(relativePath);
708
+ return await withHeldFileLock(
709
+ lockPath,
710
+ { staleMs: CAS_REVISION_LOCK_STALE_MS, maxWaitMs: CAS_REVISION_LOCK_MAX_WAIT_MS },
711
+ async (acquired, lock) => {
712
+ if (!acquired) throw new Error("CAS revision lock is unavailable.");
713
+ return await task(lock);
714
+ }
715
+ );
716
+ }
717
+ /** The target's standing revision token, or undefined when no receipt was
718
+ * ever minted for it. Fail-open on storage/read errors. */
719
+ async readRevision(filePath) {
720
+ try {
721
+ const relativePath = await this.resolveRelativePath(filePath);
722
+ return (await this.readStandingRevision(relativePath))?.revision;
723
+ } catch (error) {
724
+ log.warn(`CasRevisionStore.readRevision failed for ${filePath}: ${error}`);
725
+ return void 0;
726
+ }
727
+ }
728
+ /** #2813 (P1 A): the truthful standing-receipt read. `absent` means no
729
+ * receipt was ever minted for the target — undefined semantics stay
730
+ * correct for those records. `unavailable` means the sidecar could not
731
+ * be read OR a reservation is pending finalization; callers that
732
+ * transact on receipt identity MUST refuse rather than treat the
733
+ * failure as absence. */
734
+ async readRevisionStatus(filePath) {
735
+ try {
736
+ const relativePath = await this.resolveRelativePath(filePath);
737
+ const standing = await this.readStandingRevisionStrict(relativePath);
738
+ return standing === void 0 ? { status: "absent" } : {
739
+ status: "present",
740
+ revision: standing.revision,
741
+ ...standing.committedDigest !== void 0 ? { committedDigest: standing.committedDigest } : {},
742
+ ...standing.committedSemanticFingerprint !== void 0 ? { committedSemanticFingerprint: standing.committedSemanticFingerprint } : {}
743
+ };
744
+ } catch (error) {
745
+ return { status: "unavailable", reason: error instanceof Error ? error.message : String(error) };
746
+ }
747
+ }
748
+ /** #2813 (P1 C): reserve the NEXT revision token as a durable PENDING
749
+ * marker under the target's shard lock — the write-ahead record of a
750
+ * receipt transaction. The token is strictly greater than the standing
751
+ * token (max(clock, prev + 1ms)), so two commits can never share a
752
+ * receipt — not within one millisecond, not across a backward clock
753
+ * step. Refuses while another reservation is pending (recovery needed)
754
+ * or the standing receipt cannot be determined. The caller MUST either
755
+ * `commit` after its durable write lands or `abort` when it fails.
756
+ * #2807: the marker records the reserve-time fingerprint (`baselineDigest`)
757
+ * and optional expected post-write fingerprint (`expectedDigest`) with
758
+ * `writeLanded: false`. {@link recoverPendingRevision} decides crashes
759
+ * before or after the memory write from that evidence. */
760
+ async beginRevisionTransaction(filePath, expectedContent) {
761
+ const relativePath = await this.resolveRelativePath(filePath);
762
+ return await this.withShardLock(relativePath, async (lock) => {
763
+ const standingInfo = await this.readStandingRevisionStrict(relativePath);
764
+ const standing = standingInfo?.revision;
765
+ const next = nextCasRevisionIso(standing);
766
+ const baselineDigest = await this.digestDurableFile(relativePath);
767
+ const expectedDigest = expectedContent != null ? this.digestContent(expectedContent) : void 0;
768
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
769
+ await this.writeShard(shardPath, relativePath, next, lock, "pending", standing, {
770
+ baselineDigest,
771
+ ...expectedDigest !== void 0 ? { expectedDigest } : {},
772
+ writeLanded: false
773
+ });
774
+ return {
775
+ pendingRevision: next,
776
+ writeLanded: () => this.recordPendingWriteLanded(relativePath, next),
777
+ commit: () => this.finalizeRevisionTransaction(relativePath, next, "commit"),
778
+ abort: () => this.finalizeRevisionTransaction(relativePath, next, "abort")
779
+ };
780
+ });
781
+ }
782
+ digestContent(content) {
783
+ const bytes = typeof content === "string" ? Buffer.from(content, "utf8") : content;
784
+ return createHash2("sha256").update(bytes).digest("hex");
785
+ }
786
+ async digestDurableFile(filePath) {
787
+ const bytes = await this.readDurableBytes(filePath);
788
+ return bytes === null ? null : createHash2("sha256").update(bytes).digest("hex");
789
+ }
790
+ /** #2870: canonical SEMANTIC fingerprint of the durable file — its text
791
+ * with the access-telemetry frontmatter keys stripped
792
+ * ({@link canonicalSemanticFileText}), hashed. Null means the file was
793
+ * absent. A fingerprint, never memory content. */
794
+ async semanticFingerprintDurableFile(filePath) {
795
+ const bytes = await this.readDurableBytes(filePath);
796
+ return bytes === null ? null : createHash2("sha256").update(canonicalSemanticFileText(bytes.toString("utf8"))).digest("hex");
797
+ }
798
+ async readDurableBytes(filePath) {
799
+ const relativePath = await this.resolveRelativePath(filePath);
800
+ const baseDir = path2.resolve(this.baseDir);
801
+ const target = await resolveSafeStoragePath(baseDir, relativePath);
802
+ try {
803
+ return await readFile2(target);
804
+ } catch (error) {
805
+ if (isErrnoCode(error, "ENOENT")) return null;
806
+ throw new Error(
807
+ `CAS revision evidence: durable memory file ${relativePath} is unreadable: ${error instanceof Error ? error.message : String(error)}`
808
+ );
809
+ }
810
+ }
811
+ /** #2807: mark the reserved write as landed. Verifies a pre-recorded
812
+ * expected digest against the durable file, or records the file digest
813
+ * when none was reserved. Sets `writeLanded: true`. Idempotent. */
814
+ async recordPendingWriteLanded(relativePath, token) {
815
+ await this.withShardLock(relativePath, async (lock) => {
816
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
817
+ const view = await this.readShardView(shardPath, relativePath);
818
+ if (view.kind !== "pending" || view.foreign || view.revision !== token) {
819
+ throw new Error(
820
+ `CAS revision evidence recording refused for ${relativePath}: the pending marker does not match the reserved token.`
821
+ );
822
+ }
823
+ if (pendingWriteHasLanded(view) && view.writeLanded !== false) return;
824
+ const currentDigest = await this.digestDurableFile(relativePath);
825
+ if (view.expectedDigest !== void 0 && currentDigest !== view.expectedDigest) {
826
+ throw new Error(
827
+ `CAS revision evidence recording refused for ${relativePath}: the durable file does not match the reserved expected digest.`
828
+ );
829
+ }
830
+ await this.writeShard(shardPath, relativePath, token, lock, "pending", view.previous, {
831
+ baselineDigest: view.baselineDigest === void 0 ? null : view.baselineDigest,
832
+ expectedDigest: view.expectedDigest !== void 0 ? view.expectedDigest : currentDigest,
833
+ writeLanded: true
834
+ });
835
+ });
836
+ }
837
+ async finalizeRevisionTransaction(relativePath, token, outcome) {
838
+ await this.withShardLock(relativePath, async (lock) => {
839
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
840
+ const view = await this.readShardView(shardPath, relativePath);
841
+ if (view.kind === "pending" && !view.foreign && view.revision === token) {
842
+ if (outcome === "commit") {
843
+ const committedDigest = view.expectedDigest ?? await this.digestDurableFile(relativePath);
844
+ const committedSemanticFingerprint = await this.semanticFingerprintDurableFile(relativePath);
845
+ await this.writeShard(shardPath, relativePath, token, lock, "committed", void 0, {
846
+ committedDigest,
847
+ committedSemanticFingerprint
848
+ });
849
+ } else if (view.previous !== void 0) {
850
+ await this.writeShard(shardPath, relativePath, view.previous, lock, "committed");
851
+ } else {
852
+ await unlink2(shardPath);
853
+ }
854
+ return;
855
+ }
856
+ if (outcome === "commit" && view.kind === "committed" && !view.foreign && view.revision === token) {
857
+ return;
858
+ }
859
+ if (outcome === "abort" && view.kind === "missing") {
860
+ return;
861
+ }
862
+ throw new Error(
863
+ `CAS revision transaction ${outcome} refused for ${relativePath}: the pending marker does not match the reserved token.`
864
+ );
865
+ });
866
+ }
867
+ /** #2837: remove the target's receipt shard once its durable memory file
868
+ * has been deleted, so orphan shards cannot accumulate. Under the shard
869
+ * lock: a PENDING marker is crash-recovery evidence for
870
+ * {@link recoverPendingRevision} and is KEPT ("pending"); a shard naming
871
+ * another target is KEPT ("foreign") — never destroy a receipt you cannot
872
+ * attribute. Never touches the durable memory file or the legacy global
873
+ * metadata: a stale legacy entry keeps per-path monotonicity if the path
874
+ * is ever reused. */
875
+ async removeRevisionShard(filePath) {
876
+ const relativePath = await this.resolveRelativePath(filePath);
877
+ return await this.withShardLock(relativePath, async () => {
878
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
879
+ const view = await this.readShardView(shardPath, relativePath);
880
+ if (view.kind === "missing") return "absent";
881
+ if (view.kind === "pending") return view.foreign ? "foreign" : "pending";
882
+ if (view.kind === "foreign" || view.foreign) return "foreign";
883
+ await unlink2(shardPath);
884
+ return "removed";
885
+ });
886
+ }
887
+ /** #2813 (P1 C): recovery for a reservation left PENDING by a crash or a
888
+ * failed publication. The caller supplies the KNOWN outcome of the
889
+ * durable memory write: `fileWriteLanded` publishes the pending token as
890
+ * the COMMITTED receipt; otherwise the reservation is discarded and the
891
+ * previous standing token restored. Idempotent — an already-committed or
892
+ * absent shard is reported, not mutated. */
893
+ async reconcilePendingRevision(filePath, fileWriteLanded) {
894
+ const relativePath = await this.resolveRelativePath(filePath);
895
+ return await this.withShardLock(relativePath, async (lock) => {
896
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
897
+ const view = await this.readShardView(shardPath, relativePath);
898
+ if (view.kind === "committed") return "committed";
899
+ if (view.kind !== "pending") return "absent";
900
+ if (view.foreign) {
901
+ throw new Error(
902
+ `CAS revision pending marker for ${relativePath} names another target; manual recovery is required.`
903
+ );
904
+ }
905
+ if (fileWriteLanded) {
906
+ const committedDigest = view.expectedDigest ?? await this.digestDurableFile(relativePath);
907
+ const committedSemanticFingerprint = await this.semanticFingerprintDurableFile(relativePath);
908
+ await this.writeShard(shardPath, relativePath, view.revision, lock, "committed", void 0, {
909
+ committedDigest,
910
+ committedSemanticFingerprint
911
+ });
912
+ } else if (view.previous !== void 0) {
913
+ await this.writeShard(shardPath, relativePath, view.previous, lock, "committed");
914
+ } else {
915
+ await unlink2(shardPath);
916
+ }
917
+ return "reconciled";
918
+ });
919
+ }
920
+ /** #2807 (P1): evidence-based recovery for a reservation left PENDING by
921
+ * a crash between reserve and finalize. Under the shard lock, the durable
922
+ * file's current fingerprint is compared against the marker:
923
+ * - matches `expectedDigest` → publish the pending token as COMMITTED;
924
+ * - matches `baselineDigest` (including both absent) → abort and restore;
925
+ * - anything else THROWS. Recovery never guesses.
926
+ *
927
+ * `onlyWithWriteEvidence` is the unlocked read path. A marker whose write
928
+ * has not landed (`writeLanded` false, or legacy with no expectedDigest)
929
+ * may belong to a live writer, so it returns `reserved`. A landed marker
930
+ * whose file no longer matches `expectedDigest` throws ambiguity. */
931
+ async recoverPendingRevision(filePath, options) {
932
+ const relativePath = await this.resolveRelativePath(filePath);
933
+ return await this.withShardLock(relativePath, async (lock) => {
934
+ const { shardPath } = await this.getSafeShardInfo(relativePath);
935
+ const view = await this.readShardView(shardPath, relativePath);
936
+ if (view.kind === "missing" || view.kind === "foreign") return "absent";
937
+ if (view.kind === "committed") return view.foreign ? "absent" : "committed";
938
+ if (view.foreign) {
939
+ throw new Error(
940
+ `CAS revision pending marker for ${relativePath} names another target; manual recovery is required.`
941
+ );
942
+ }
943
+ const currentDigest = await this.digestDurableFile(relativePath);
944
+ const landed = pendingWriteHasLanded(view);
945
+ if (options?.onlyWithWriteEvidence && !landed) {
946
+ return "reserved";
947
+ }
948
+ if (view.expectedDigest !== void 0 && currentDigest === view.expectedDigest) {
949
+ await this.writeShard(shardPath, relativePath, view.revision, lock, "committed", void 0, {
950
+ committedDigest: view.expectedDigest,
951
+ committedSemanticFingerprint: await this.semanticFingerprintDurableFile(relativePath)
952
+ });
953
+ return "committed";
954
+ }
955
+ if (options?.onlyWithWriteEvidence) {
956
+ const evidence2 = view.expectedDigest === void 0 ? "the pending marker carries no crash evidence (written by an older version)" : "the durable file matches neither the expected commit fingerprint nor the reserve-time baseline";
957
+ throw new Error(
958
+ `CAS revision recovery for ${relativePath} is ambiguous: ${evidence2} (pending token ${view.revision}${view.previous !== void 0 ? `, previous ${view.previous}` : ""}). Inspect the durable file and the shard at ${shardPath}, then run reconcilePendingRevision with the known write outcome. Refusing to guess.`
959
+ );
960
+ }
961
+ if (view.baselineDigest !== void 0 && currentDigest === view.baselineDigest) {
962
+ if (view.previous !== void 0) {
963
+ await this.writeShard(shardPath, relativePath, view.previous, lock, "committed");
964
+ } else {
965
+ await unlink2(shardPath);
966
+ }
967
+ return "aborted";
968
+ }
969
+ const evidence = view.baselineDigest === void 0 && view.expectedDigest === void 0 ? "the pending marker carries no crash evidence (written by an older version)" : "the durable file matches neither the expected commit fingerprint nor the reserve-time baseline";
970
+ throw new Error(
971
+ `CAS revision recovery for ${relativePath} is ambiguous: ${evidence} (pending token ${view.revision}${view.previous !== void 0 ? `, previous ${view.previous}` : ""}). Inspect the durable file and the shard at ${shardPath}, then run reconcilePendingRevision with the known write outcome. Refusing to guess.`
972
+ );
973
+ });
974
+ }
975
+ };
976
+
977
+ // src/storage/cas-revision-host.ts
978
+ var CasRevisionHost = class extends CasRevisionStore {
979
+ /** Standing CAS revision token — receipt identity, never public `updated` (#2807). Fail-open on read errors. */
980
+ async readCasRevision(filePath) {
981
+ try {
982
+ return await this.readRevision(filePath);
983
+ } catch (err) {
984
+ log.warn(`storage.readCasRevision failed for ${filePath}: ${err}`);
985
+ return void 0;
986
+ }
987
+ }
988
+ /** #2813 (P1 A): truthful CAS receipt probe — distinguishes a genuinely
989
+ * ABSENT receipt (target predates the sidecar; `undefined` semantics stay
990
+ * correct) from an UNAVAILABLE one (unreadable shard: receipt identity is
991
+ * unknown). Transactional callers that must refuse on unknown identity
992
+ * route here; `readCasRevision` stays fail-open for advisory reads.
993
+ * #2807 (P1): a PENDING marker left by a crash is lazily recovered on
994
+ * this first read when its evidence is decisive; a reserve-only marker
995
+ * may belong to a live writer and defers to the path-locked write path,
996
+ * and ambiguity stays `unavailable` with an actionable reason. */
997
+ async readCasRevisionStatus(filePath) {
998
+ const status = await this.readRevisionStatus(filePath);
999
+ if (status.status !== "unavailable" || !/pending/i.test(status.reason)) return status;
1000
+ try {
1001
+ const outcome = await this.recoverPendingRevision(filePath, {
1002
+ onlyWithWriteEvidence: true
1003
+ });
1004
+ if (outcome === "reserved") return status;
1005
+ } catch (error) {
1006
+ return {
1007
+ status: "unavailable",
1008
+ reason: error instanceof Error ? error.message : String(error)
1009
+ };
1010
+ }
1011
+ return await this.readRevisionStatus(filePath);
1012
+ }
1013
+ async readDurableFileDigest(filePath) {
1014
+ try {
1015
+ return await this.digestDurableFile(filePath);
1016
+ } catch (err) {
1017
+ log.warn(`storage.readDurableFileDigest failed for ${filePath}: ${err}`);
1018
+ return null;
1019
+ }
1020
+ }
1021
+ /** #2807 (P1): reconcile any crash-orphaned PENDING marker for this
1022
+ * target BEFORE the next semantic mutation reserves a new token —
1023
+ * otherwise a crashed reservation would make the memory permanently
1024
+ * unwritable. Decisive evidence heals; ambiguity throws so the
1025
+ * mutation fails closed with the actionable recovery error. */
1026
+ async beginRevision(pathname, expectedContent) {
1027
+ await this.recoverPendingRevision(pathname);
1028
+ return await this.beginRevisionTransaction(pathname, expectedContent);
1029
+ }
1030
+ /** #2837: best-effort post-deletion sweep of the target's receipt shard.
1031
+ * The durable memory file is already gone, so a failed sweep must never
1032
+ * fail the deletion itself — it logs instead. A PENDING shard (crash
1033
+ * recovery evidence) and a foreign shard (another target's receipt) are
1034
+ * kept, with a warning naming the recovery path. */
1035
+ async sweepShardAfterDeletion(filePath) {
1036
+ try {
1037
+ const outcome = await this.removeRevisionShard(filePath);
1038
+ if (outcome === "pending") {
1039
+ log.warn(
1040
+ `CAS revision shard for ${filePath} kept after memory deletion: a pending reservation stands \u2014 run recovery before the path is reused`
1041
+ );
1042
+ } else if (outcome === "foreign") {
1043
+ log.warn(
1044
+ `CAS revision shard for ${filePath} kept after memory deletion: the shard names another target`
1045
+ );
1046
+ }
1047
+ } catch (err) {
1048
+ log.warn(`failed to sweep CAS revision shard for deleted memory ${filePath}: ${err}`);
1049
+ }
1050
+ }
1051
+ };
1052
+
478
1053
  // src/storage/tombstone-blocked-capture-mutation.ts
479
1054
  import { AsyncLocalStorage } from "async_hooks";
480
- import { createHash as createHash2 } from "crypto";
481
- import { mkdir as mkdir2 } from "fs/promises";
482
- import path2 from "path";
1055
+ import { createHash as createHash3 } from "crypto";
1056
+ import { mkdir as mkdir3 } from "fs/promises";
1057
+ import path3 from "path";
483
1058
  var TOMBSTONE_CAPTURE_WRITE_LOCK_STALE_MS = 6e4;
484
1059
  var CAPTURE_WRITE_LOCK_MAX_ATTEMPTS = 3;
485
1060
  var CAPTURE_WRITE_LOCK_RETRY_BASE_MS = 25;
@@ -502,7 +1077,7 @@ function buildCapturePathLockIdentity(pathname) {
502
1077
  return `path ${pathname.length} ${pathname}`;
503
1078
  }
504
1079
  function captureIdentityHash(memory) {
505
- return createHash2("sha256").update(
1080
+ return createHash3("sha256").update(
506
1081
  buildExplicitCaptureDedupKey(memory.content, memory.frontmatter.category, memory.frontmatter.sourceConnector)
507
1082
  ).digest("hex");
508
1083
  }
@@ -514,10 +1089,10 @@ var TombstoneBlockedCaptureWriteLock = class {
514
1089
  context = new AsyncLocalStorage();
515
1090
  captureWriteLockPathForHash(identityHash) {
516
1091
  const filename = identityHash.length === 0 ? "explicit-capture-write.lock" : `explicit-capture-write-${identityHash}.lock`;
517
- return path2.join(this.options.stateDir, "tombstone-blocked-capture", filename);
1092
+ return path3.join(this.options.stateDir, "tombstone-blocked-capture", filename);
518
1093
  }
519
1094
  async withSingleCaptureWriteLock(lockPath, task) {
520
- await mkdir2(path2.dirname(lockPath), { recursive: true });
1095
+ await mkdir3(path3.dirname(lockPath), { recursive: true });
521
1096
  const retry = /* @__PURE__ */ Symbol("retry");
522
1097
  const permanentFailure = /* @__PURE__ */ Symbol("permanent-failure");
523
1098
  const runWithHeldFileLock = this.options.withHeldFileLock ?? withHeldFileLock;
@@ -566,8 +1141,8 @@ var TombstoneBlockedCaptureWriteLock = class {
566
1141
  }
567
1142
  async withCaptureWriteLocks(task, identities, identityHashes) {
568
1143
  const current = this.context.getStore();
569
- const hashToken = (key) => `\0${key.length === 0 ? "" : createHash2("sha256").update(key).digest("hex")}`;
570
- const identityHash = (key) => key.length === 0 ? "" : createHash2("sha256").update(key).digest("hex");
1144
+ const hashToken = (key) => `\0${key.length === 0 ? "" : createHash3("sha256").update(key).digest("hex")}`;
1145
+ const identityHash = (key) => key.length === 0 ? "" : createHash3("sha256").update(key).digest("hex");
571
1146
  const identityKeys = [...new Set(identities)];
572
1147
  const hashes = [...new Set(identityHashes)];
573
1148
  const requested = [
@@ -695,16 +1270,16 @@ function isQueuedReviewMemory(memory) {
695
1270
  }
696
1271
 
697
1272
  // src/storage/tombstone-blocked-capture-sync.ts
698
- import { createHash as createHash3, randomUUID as randomUUID3 } from "crypto";
699
- import { unlink as unlink3 } from "fs/promises";
700
- import path4 from "path";
1273
+ import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
1274
+ import { unlink as unlink4 } from "fs/promises";
1275
+ import path5 from "path";
701
1276
  import { isDeepStrictEqual } from "util";
702
1277
 
703
1278
  // src/storage/tombstone-blocked-capture-index.ts
704
1279
  import { execFile } from "child_process";
705
- import { randomUUID as randomUUID2 } from "crypto";
706
- import { mkdir as mkdir3, readFile as readFile2, readdir, rename as rename2, stat, unlink as unlink2, writeFile } from "fs/promises";
707
- import path3 from "path";
1280
+ import { randomUUID as randomUUID3 } from "crypto";
1281
+ import { mkdir as mkdir4, readFile as readFile3, readdir, rename as rename3, stat, unlink as unlink3, writeFile } from "fs/promises";
1282
+ import path4 from "path";
708
1283
  import { promisify } from "util";
709
1284
  var REBUILD_MAX_ATTEMPTS = 3;
710
1285
  var execFileAsync = promisify(execFile);
@@ -726,7 +1301,7 @@ var TombstoneBlockedCaptureIndex = class {
726
1301
  }
727
1302
  createIndex() {
728
1303
  return new ContentHashIndex(
729
- path3.join(this.options.stateDir, "tombstone-blocked-capture"),
1304
+ path4.join(this.options.stateDir, "tombstone-blocked-capture"),
730
1305
  this.options.secureStoreKeyProvider,
731
1306
  this.options.secureStoreWriteKeyProvider,
732
1307
  this.options.memoryDir,
@@ -734,19 +1309,19 @@ var TombstoneBlockedCaptureIndex = class {
734
1309
  );
735
1310
  }
736
1311
  indexPath() {
737
- return path3.join(this.options.stateDir, "tombstone-blocked-capture", "fact-hashes.txt");
1312
+ return path4.join(this.options.stateDir, "tombstone-blocked-capture", "fact-hashes.txt");
738
1313
  }
739
1314
  rebuildMarkerPath() {
740
- return path3.join(this.options.stateDir, "tombstone-blocked-capture", "rebuild-required");
1315
+ return path4.join(this.options.stateDir, "tombstone-blocked-capture", "rebuild-required");
741
1316
  }
742
1317
  async readRebuildMarkers() {
743
1318
  try {
744
1319
  const entries = (await readdir(this.rebuildMarkerPath())).filter((entry) => !entry.startsWith("."));
745
1320
  return (await Promise.all(
746
1321
  entries.map(async (entry) => {
747
- const markerPath = path3.join(this.rebuildMarkerPath(), entry);
1322
+ const markerPath = path4.join(this.rebuildMarkerPath(), entry);
748
1323
  try {
749
- const raw = (await readFile2(markerPath, "utf8")).trim();
1324
+ const raw = (await readFile3(markerPath, "utf8")).trim();
750
1325
  if (raw === "committed") return { path: markerPath, committed: true };
751
1326
  let value;
752
1327
  let malformed = false;
@@ -767,7 +1342,7 @@ var TombstoneBlockedCaptureIndex = class {
767
1342
  const markerStat = await stat(markerPath).catch(() => null);
768
1343
  const createdAt = typeof value.createdAt === "number" && Number.isFinite(value.createdAt) ? value.createdAt : markerStat?.mtimeMs;
769
1344
  if (typeof value.pid !== "number" || !Number.isInteger(value.pid)) malformed = true;
770
- const ownerId = typeof value.ownerId === "string" && value.ownerId.length > 0 ? value.ownerId : path3.basename(markerPath);
1345
+ const ownerId = typeof value.ownerId === "string" && value.ownerId.length > 0 ? value.ownerId : path4.basename(markerPath);
771
1346
  if (typeof value.ownerId !== "string" || value.ownerId.length === 0) malformed = true;
772
1347
  const processStartedAtMs = typeof value.processStartedAtMs === "number" && Number.isFinite(value.processStartedAtMs) && value.processStartedAtMs > 0 ? value.processStartedAtMs : void 0;
773
1348
  return {
@@ -847,21 +1422,21 @@ var TombstoneBlockedCaptureIndex = class {
847
1422
  }
848
1423
  // A pending marker protects the pre-commit gap; only committed markers are safe for another writer to clear.
849
1424
  async writeMarkerAtomically(markerPath, payload) {
850
- const temporaryPath = `${markerPath}.tmp-${process.pid}-${randomUUID2()}`;
1425
+ const temporaryPath = `${markerPath}.tmp-${process.pid}-${randomUUID3()}`;
851
1426
  try {
852
1427
  await writeFile(temporaryPath, payload, "utf8");
853
- await rename2(temporaryPath, markerPath);
1428
+ await rename3(temporaryPath, markerPath);
854
1429
  } finally {
855
- await unlink2(temporaryPath).catch((err) => {
1430
+ await unlink3(temporaryPath).catch((err) => {
856
1431
  if (!isErrnoCode(err, "ENOENT")) throw err;
857
1432
  });
858
1433
  }
859
1434
  }
860
1435
  async markRebuildRequired(committed = false) {
861
1436
  const markerDir = this.rebuildMarkerPath();
862
- await mkdir3(markerDir, { recursive: true });
863
- const ownerId = randomUUID2();
864
- const markerPath = path3.join(markerDir, ownerId);
1437
+ await mkdir4(markerDir, { recursive: true });
1438
+ const ownerId = randomUUID3();
1439
+ const markerPath = path4.join(markerDir, ownerId);
865
1440
  await this.writeMarkerAtomically(
866
1441
  markerPath,
867
1442
  `${JSON.stringify({
@@ -881,7 +1456,7 @@ var TombstoneBlockedCaptureIndex = class {
881
1456
  `${JSON.stringify({
882
1457
  state: "committed",
883
1458
  pid: process.pid,
884
- ownerId: path3.basename(markerPath),
1459
+ ownerId: path4.basename(markerPath),
885
1460
  createdAt: Date.now(),
886
1461
  processStartedAtMs: MARKER_PROCESS_STARTED_AT_MS
887
1462
  })}
@@ -892,7 +1467,7 @@ var TombstoneBlockedCaptureIndex = class {
892
1467
  await Promise.all(
893
1468
  markerPaths.map(async (markerPath) => {
894
1469
  try {
895
- await unlink2(markerPath);
1470
+ await unlink3(markerPath);
896
1471
  } catch (err) {
897
1472
  if (!isErrnoCode(err, "ENOENT")) throw err;
898
1473
  }
@@ -1133,8 +1708,8 @@ var TombstoneBlockedCaptureIndex = class {
1133
1708
  await this.failOpen("writeMemoryFrontmatter", () => this.sync(before, { ...before, frontmatter }, rebuildMarker));
1134
1709
  }
1135
1710
  shouldRebuildAfterInvalidationForPath(filePath) {
1136
- const relative = path3.relative(path3.resolve(this.options.memoryDir), path3.resolve(filePath));
1137
- const category = relative.split(path3.sep)[0];
1711
+ const relative = path4.relative(path4.resolve(this.options.memoryDir), path4.resolve(filePath));
1712
+ const category = relative.split(path4.sep)[0];
1138
1713
  return category === "cold" || RECALL_FALLBACK_DIRS.includes(category);
1139
1714
  }
1140
1715
  };
@@ -1271,6 +1846,24 @@ var TombstoneBlockedCaptureIndexHost = class {
1271
1846
  async beginDurableMemoryRevision(_pathname, _expectedContent) {
1272
1847
  return void 0;
1273
1848
  }
1849
+ /** #2837 (shard cleanup): after a managed memory file is durably deleted,
1850
+ * sweep its per-target CAS receipt shard so orphan shards cannot grow
1851
+ * forever. The sweep runs under the shard's own lock and is best-effort —
1852
+ * the memory file is already gone, so a sweep failure logs and never
1853
+ * fails the delete. The sweeper is a second CasRevisionHost over the same
1854
+ * memory dir; the host is stateless and every mutation serializes through
1855
+ * the sidecar's file locks, so it shares the same shard files
1856
+ * StorageManager's own host operates on. */
1857
+ deletedMemoryShardSweeper = null;
1858
+ async deleteManagedStorageFile(filePath, deletionMtimeMs) {
1859
+ const deleted = await this.deleteManagedStorageFileDurable(filePath, deletionMtimeMs);
1860
+ if (!deleted) return false;
1861
+ if (this.deletedMemoryShardSweeper === null) {
1862
+ this.deletedMemoryShardSweeper = new CasRevisionHost(this.tombstoneBlockedCaptureIndexOptions().memoryDir);
1863
+ }
1864
+ await this.deletedMemoryShardSweeper.sweepShardAfterDeletion(filePath);
1865
+ return true;
1866
+ }
1274
1867
  async writeStorageSecureFileChunks(filePath, chunks) {
1275
1868
  const options = this.tombstoneBlockedCaptureIndexOptions();
1276
1869
  await writeMaybeEncryptedFileFromChunks(
@@ -1477,7 +2070,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1477
2070
  this.invalidateAllMemoriesCache();
1478
2071
  this.invalidateKnowledgeIndexCache();
1479
2072
  this.markFactHashIndexNotAuthoritative();
1480
- if (filePath.includes(`${path4.sep}cold${path4.sep}`)) {
2073
+ if (filePath.includes(`${path5.sep}cold${path5.sep}`)) {
1481
2074
  this.invalidateColdMemoriesCache();
1482
2075
  }
1483
2076
  if (blockedKeySetMayHaveChanged) {
@@ -1490,7 +2083,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1490
2083
  log.warn(`storage.offlineSyncFile committed write succeeded; marker cleanup failed: ${err}`);
1491
2084
  }
1492
2085
  }
1493
- if (filePath.includes(`${path4.sep}artifacts${path4.sep}`)) {
2086
+ if (filePath.includes(`${path5.sep}artifacts${path5.sep}`)) {
1494
2087
  this.bumpArtifactWriteVersion();
1495
2088
  }
1496
2089
  const memoryDir = this.tombstoneBlockedCaptureIndexOptions().memoryDir;
@@ -1585,7 +2178,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1585
2178
  bumpArchiveMutationForPath(memoryDir, true, current.path);
1586
2179
  markProjectedMemoryPathInvalid(memoryDir, current.frontmatter.id);
1587
2180
  this.invalidateAllMemoriesCache();
1588
- if (current.path.includes(`${path4.sep}cold${path4.sep}`)) {
2181
+ if (current.path.includes(`${path5.sep}cold${path5.sep}`)) {
1589
2182
  this.invalidateColdMemoriesCache();
1590
2183
  }
1591
2184
  await this.rebuildTombstoneBlockedCaptureAfterInvalidation(rebuildMarker);
@@ -1668,7 +2261,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1668
2261
  async writeTombstoneBlockedOfflineSyncFile(target, content) {
1669
2262
  const options = this.tombstoneBlockedCaptureIndexOptions();
1670
2263
  const after = options.parseMemory?.(target, content) ?? null;
1671
- await withRawEntityPageMutation(path4.dirname(options.stateDir), target, async () => {
2264
+ await withRawEntityPageMutation(path5.dirname(options.stateDir), target, async () => {
1672
2265
  await this.runTombstoneBlockedOfflineSyncMutation(
1673
2266
  target,
1674
2267
  after,
@@ -1707,11 +2300,11 @@ var TombstoneBlockedCaptureIndexHost = class {
1707
2300
  return { after, chunks: replay };
1708
2301
  }
1709
2302
  const options = this.tombstoneBlockedCaptureIndexOptions();
1710
- const stagePath = path4.join(
2303
+ const stagePath = path5.join(
1711
2304
  options.stateDir,
1712
2305
  "tombstone-blocked-capture",
1713
2306
  "offline-sync-staging",
1714
- `${randomUUID3()}.stage`
2307
+ `${randomUUID4()}.stage`
1715
2308
  );
1716
2309
  const stagedChunks = (async function* () {
1717
2310
  for (const chunk of buffered) yield chunk;
@@ -1732,7 +2325,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1732
2325
  );
1733
2326
  return await this.describeStagedOfflineSyncChunks(target, stagePath, parseMemory);
1734
2327
  } catch (err) {
1735
- await unlink3(stagePath).catch(() => {
2328
+ await unlink4(stagePath).catch(() => {
1736
2329
  });
1737
2330
  throw err;
1738
2331
  }
@@ -1786,7 +2379,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1786
2379
  encode("connector", connector),
1787
2380
  `content ${normalizedLength} `
1788
2381
  ].join(" ");
1789
- let identityHash = createHash3("sha256");
2382
+ let identityHash = createHash4("sha256");
1790
2383
  let normalSigmaIdentityHash;
1791
2384
  identityHash.update(identityPrefix);
1792
2385
  const identityNormalizer = createExplicitContentNormalizer({
@@ -1832,7 +2425,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1832
2425
  const coordinate = this.getTombstoneBlockedCaptureIndex().shouldRebuildAfterInvalidationForPath(target);
1833
2426
  const prepared = coordinate ? await this.prepareTombstoneBlockedOfflineSyncChunks(target, chunks) : { after: null, chunks };
1834
2427
  const streamedIdentity = prepared.streamedIdentity;
1835
- const baseDir = path4.dirname(this.tombstoneBlockedCaptureIndexOptions().stateDir);
2428
+ const baseDir = path5.dirname(this.tombstoneBlockedCaptureIndexOptions().stateDir);
1836
2429
  try {
1837
2430
  await withRawEntityPageMutation(baseDir, target, async () => {
1838
2431
  await this.runTombstoneBlockedOfflineSyncMutation(
@@ -1844,7 +2437,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1844
2437
  );
1845
2438
  });
1846
2439
  } finally {
1847
- if (prepared.stagePath !== void 0) await unlink3(prepared.stagePath).catch(() => {
2440
+ if (prepared.stagePath !== void 0) await unlink4(prepared.stagePath).catch(() => {
1848
2441
  });
1849
2442
  }
1850
2443
  }
@@ -1864,7 +2457,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1864
2457
  */
1865
2458
  async requestSyncReconcileIfMigrationPath(target) {
1866
2459
  const stateDir = this.tombstoneBlockedCaptureIndexOptions().stateDir;
1867
- if (!pathMayCarryEntityRefs(path4.dirname(stateDir), target)) return;
2460
+ if (!pathMayCarryEntityRefs(path5.dirname(stateDir), target)) return;
1868
2461
  await requestEntityCanonicalIdReconcile(stateDir);
1869
2462
  }
1870
2463
  async deleteOfflineSyncFile(filePath, deletionMtimeMs) {
@@ -1874,7 +2467,7 @@ var TombstoneBlockedCaptureIndexHost = class {
1874
2467
  }
1875
2468
  async deleteTombstoneBlockedOfflineSyncFile(target, deletionMtimeMs) {
1876
2469
  const stateDir = this.tombstoneBlockedCaptureIndexOptions().stateDir;
1877
- await withRawEntityPageMutation(path4.dirname(stateDir), target, async () => {
2470
+ await withRawEntityPageMutation(path5.dirname(stateDir), target, async () => {
1878
2471
  await this.runTombstoneBlockedOfflineSyncMutation(target, null, async () => {
1879
2472
  return await this.deleteManagedStorageFile(target, deletionMtimeMs);
1880
2473
  });
@@ -1903,10 +2496,10 @@ var TombstoneBlockedCaptureIndexHost = class {
1903
2496
  export {
1904
2497
  invalidationCommitFingerprint,
1905
2498
  casCommittedRevisionOf,
1906
- nextCasRevisionIso,
1907
2499
  withCasCommitReceipt,
1908
- isValidManagedStoragePath,
1909
2500
  DeletionRevisionStore,
2501
+ canonicalSemanticFileText,
2502
+ CasRevisionHost,
1910
2503
  isTombstoneBlockedCaptureWriteLockBusy,
1911
2504
  normalizeExplicitCaptureContent,
1912
2505
  buildExplicitCaptureDedupKey,
@@ -1916,4 +2509,4 @@ export {
1916
2509
  parseTombstoneBlockedOfflineSyncMemory,
1917
2510
  TombstoneBlockedCaptureIndexHost
1918
2511
  };
1919
- //# sourceMappingURL=chunk-SHEHQBCG.js.map
2512
+ //# sourceMappingURL=chunk-DUJYRVUD.js.map