@remnic/core 9.27.0 → 9.28.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 (439) hide show
  1. package/dist/access-admin-ops-surface.d.ts +13 -10
  2. package/dist/access-admin-ops-surface.js +43 -38
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +13 -10
  5. package/dist/access-authorization-probe.js +44 -39
  6. package/dist/access-boundary.d.ts +13 -10
  7. package/dist/access-boundary.js +43 -38
  8. package/dist/access-cli.js +100 -94
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-health-types.d.ts +10 -1
  11. package/dist/access-http-lcm-compaction.d.ts +13 -10
  12. package/dist/access-http.d.ts +13 -10
  13. package/dist/access-http.js +53 -48
  14. package/dist/access-identity-continuity-surface.d.ts +9 -8
  15. package/dist/access-identity-continuity-surface.js +43 -38
  16. package/dist/access-lcm-surface.d.ts +13 -10
  17. package/dist/access-lcm-surface.js +43 -38
  18. package/dist/access-mcp.d.ts +13 -10
  19. package/dist/access-mcp.js +48 -43
  20. package/dist/access-memory-search-fanout.d.ts +2 -2
  21. package/dist/{access-namespace-preflight-wRSZEO5V.d.ts → access-namespace-preflight-BiQ_-iUJ.d.ts} +1 -1
  22. package/dist/access-namespace-preflight.d.ts +3 -3
  23. package/dist/access-namespace-preflight.js +43 -38
  24. package/dist/access-observe-write-surface.d.ts +13 -10
  25. package/dist/access-observe-write-surface.js +43 -38
  26. package/dist/access-operations-batch.js +45 -40
  27. package/dist/access-operations.d.ts +16 -13
  28. package/dist/access-operations.js +47 -42
  29. package/dist/access-recall-concurrency.d.ts +13 -10
  30. package/dist/access-recall-concurrency.js +43 -38
  31. package/dist/access-recall-response.d.ts +13 -10
  32. package/dist/access-recall-response.js +43 -38
  33. package/dist/access-recall-surface.d.ts +13 -10
  34. package/dist/access-recall-surface.js +43 -38
  35. package/dist/access-schema.d.ts +80 -80
  36. package/dist/access-schema.js +4 -4
  37. package/dist/{access-service-B4-Fu9x2.d.ts → access-service-CXkIgcGh.d.ts} +12 -8
  38. package/dist/access-service.d.ts +13 -10
  39. package/dist/access-service.js +43 -38
  40. package/dist/access-surface-catalog.d.ts +13 -10
  41. package/dist/access-wearables-meetings-surface.d.ts +4 -3
  42. package/dist/action-confidence.d.ts +1 -1
  43. package/dist/active-memory-bridge.d.ts +1 -1
  44. package/dist/active-recall.d.ts +1 -1
  45. package/dist/active-recall.js +4 -2
  46. package/dist/active-recall.js.map +1 -1
  47. package/dist/adapters/index.js +7 -7
  48. package/dist/adapters/registry.js +3 -3
  49. package/dist/behavior-learner.d.ts +1 -1
  50. package/dist/behavior-signals.d.ts +1 -1
  51. package/dist/bootstrap.d.ts +9 -8
  52. package/dist/briefing.d.ts +3 -2
  53. package/dist/briefing.js +12 -10
  54. package/dist/buffer-surprise-report.d.ts +1 -1
  55. package/dist/buffer.d.ts +3 -2
  56. package/dist/bulk-import/index.d.ts +3 -3
  57. package/dist/calibration.d.ts +1 -1
  58. package/dist/capabilities.d.ts +1 -1
  59. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
  60. package/dist/{catalog-BLLxZ5L5.d.ts → catalog-Bouj8Gfg.d.ts} +1 -1
  61. package/dist/causal-behavior.d.ts +1 -1
  62. package/dist/causal-consolidation.d.ts +1 -1
  63. package/dist/causal-consolidation.js +13 -11
  64. package/dist/causal-consolidation.js.map +1 -1
  65. package/dist/causal-trajectory-graph.d.ts +1 -1
  66. package/dist/{chunk-7RZJWZ46.js → chunk-227UFSEQ.js} +5 -5
  67. package/dist/{chunk-UT3OQPFA.js → chunk-2BEJ4XCF.js} +2 -2
  68. package/dist/{chunk-EOLC6EXV.js → chunk-2FYNLDKJ.js} +24 -3
  69. package/dist/chunk-2FYNLDKJ.js.map +1 -0
  70. package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
  71. package/dist/{chunk-6NNNURLK.js → chunk-2PHX3I5C.js} +8 -8
  72. package/dist/{chunk-HORJVJ6K.js → chunk-2TQ2UFKH.js} +65 -60
  73. package/dist/chunk-2TQ2UFKH.js.map +1 -0
  74. package/dist/{chunk-RPA2RX5P.js → chunk-3BSJBIZ3.js} +2 -2
  75. package/dist/{chunk-JCVQV6QX.js → chunk-3UOSVTFR.js} +11 -11
  76. package/dist/{chunk-AJ7QCSIS.js → chunk-7CPOZH6Y.js} +2 -2
  77. package/dist/{chunk-MEBQFQ26.js → chunk-AHFZXUZM.js} +7 -5
  78. package/dist/chunk-AHFZXUZM.js.map +1 -0
  79. package/dist/{chunk-U3TH5Q2Q.js → chunk-ALTP3MFS.js} +2 -2
  80. package/dist/{chunk-77CNV7DY.js → chunk-BLAKS3CP.js} +4 -4
  81. package/dist/{chunk-XQ4EH6DI.js → chunk-BR4UFMLO.js} +2 -2
  82. package/dist/chunk-CVILPI77.js +432 -0
  83. package/dist/chunk-CVILPI77.js.map +1 -0
  84. package/dist/{chunk-WEAO45M4.js → chunk-DKQM5Q6Q.js} +2 -2
  85. package/dist/{chunk-CSXHRAJJ.js → chunk-EG64LXKL.js} +3 -3
  86. package/dist/{chunk-PTN6UAUA.js → chunk-ES36HTSC.js} +4 -4
  87. package/dist/{chunk-5BRT4Z2I.js → chunk-EZWWCN7I.js} +2 -2
  88. package/dist/{chunk-XKGPIWGI.js → chunk-FBZTWUK5.js} +5 -5
  89. package/dist/{chunk-GJJBPI6I.js → chunk-FOCEI3TN.js} +6 -3
  90. package/dist/chunk-FOCEI3TN.js.map +1 -0
  91. package/dist/{chunk-FRVTCCGD.js → chunk-GJPCP5CA.js} +2 -2
  92. package/dist/{chunk-CI26JDZA.js → chunk-GQSMYXKL.js} +6 -4
  93. package/dist/{chunk-CI26JDZA.js.map → chunk-GQSMYXKL.js.map} +1 -1
  94. package/dist/{chunk-TGQ2NTWH.js → chunk-IJ6WHMFB.js} +16 -2
  95. package/dist/{chunk-TGQ2NTWH.js.map → chunk-IJ6WHMFB.js.map} +1 -1
  96. package/dist/{chunk-VDX2J7OX.js → chunk-IPLYGWQF.js} +6 -6
  97. package/dist/{chunk-YSGBD3QN.js → chunk-IYT632D5.js} +3 -3
  98. package/dist/{chunk-2QSZNTDO.js → chunk-JBPKEARU.js} +7 -7
  99. package/dist/{chunk-RSYJV25N.js → chunk-JIF3VRKQ.js} +8 -8
  100. package/dist/{chunk-V25OWXAC.js → chunk-JQ7T5VDC.js} +1 -1
  101. package/dist/chunk-JQ7T5VDC.js.map +1 -0
  102. package/dist/{chunk-EUSLKI4X.js → chunk-KKBTBUVT.js} +2 -2
  103. package/dist/{chunk-RNY3BO35.js → chunk-LIHC3T43.js} +2 -2
  104. package/dist/{chunk-RGJBM7Z3.js → chunk-MJPV4LBH.js} +79 -79
  105. package/dist/{chunk-RGJBM7Z3.js.map → chunk-MJPV4LBH.js.map} +1 -1
  106. package/dist/{chunk-UGH6VPPO.js → chunk-MWTMTW2T.js} +2 -2
  107. package/dist/{chunk-MG6MNSP4.js → chunk-MXJ3VP6S.js} +6 -6
  108. package/dist/{chunk-XKO7BM2C.js → chunk-NBNDVNJ2.js} +186 -25
  109. package/dist/chunk-NBNDVNJ2.js.map +1 -0
  110. package/dist/{chunk-M5EPMNS4.js → chunk-P2CLYN6H.js} +2 -2
  111. package/dist/{chunk-BNGPHGVZ.js → chunk-PXQM2HOG.js} +13 -6
  112. package/dist/{chunk-BNGPHGVZ.js.map → chunk-PXQM2HOG.js.map} +1 -1
  113. package/dist/{chunk-CIQXI47W.js → chunk-Q5VJUNXA.js} +1192 -268
  114. package/dist/chunk-Q5VJUNXA.js.map +1 -0
  115. package/dist/{chunk-KGTD2KZJ.js → chunk-Q6YJW6KE.js} +2 -2
  116. package/dist/{chunk-X3SQYAPP.js → chunk-R372P2EH.js} +2 -2
  117. package/dist/{chunk-4MJZTF42.js → chunk-RKXZ7P4V.js} +3 -3
  118. package/dist/chunk-RMMVQQA6.js +70 -0
  119. package/dist/chunk-RMMVQQA6.js.map +1 -0
  120. package/dist/{chunk-2RAC4JIG.js → chunk-S24E4MBQ.js} +14 -14
  121. package/dist/chunk-S24E4MBQ.js.map +1 -0
  122. package/dist/{chunk-RYHWZ52A.js → chunk-S2BBISHU.js} +4 -4
  123. package/dist/{chunk-LLISELSY.js → chunk-TBMRQZDY.js} +2 -2
  124. package/dist/{chunk-FMLKOL2Z.js → chunk-TC3VNKGX.js} +4 -4
  125. package/dist/{chunk-7K5Q6COX.js → chunk-TVVEYCNW.js} +4 -4
  126. package/dist/{chunk-NUWMZIYZ.js → chunk-UR5SIN7H.js} +53 -35
  127. package/dist/chunk-UR5SIN7H.js.map +1 -0
  128. package/dist/{chunk-JDOJZTFF.js → chunk-VFNI3RPT.js} +2 -2
  129. package/dist/chunk-VNA7W7QF.js +134 -0
  130. package/dist/chunk-VNA7W7QF.js.map +1 -0
  131. package/dist/{chunk-EYJSW2RV.js → chunk-VYYNBJXH.js} +5 -5
  132. package/dist/chunk-WNIUPHWV.js +152 -0
  133. package/dist/chunk-WNIUPHWV.js.map +1 -0
  134. package/dist/chunk-WRJVB3C2.js +118 -0
  135. package/dist/chunk-WRJVB3C2.js.map +1 -0
  136. package/dist/{chunk-BHLN7L7M.js → chunk-WVVK2RFM.js} +6 -6
  137. package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
  138. package/dist/{chunk-HEXSNYJD.js → chunk-YOBNCD3Z.js} +6 -6
  139. package/dist/chunk-YXZG5TVN.js +40 -0
  140. package/dist/chunk-YXZG5TVN.js.map +1 -0
  141. package/dist/{chunk-4DJQYKMN.js → chunk-ZIKENA2C.js} +2 -2
  142. package/dist/chunk-ZIKENA2C.js.map +1 -0
  143. package/dist/{chunk-SK3EYPKC.js → chunk-ZN4UZWMT.js} +2 -2
  144. package/dist/{cli-Bz7X7dGx.d.ts → cli-DJbkaZBU.d.ts} +5 -5
  145. package/dist/cli.d.ts +14 -12
  146. package/dist/cli.js +79 -74
  147. package/dist/compounding/engine.d.ts +3 -2
  148. package/dist/compounding/engine.js +12 -10
  149. package/dist/compounding/preference-consolidator.d.ts +1 -1
  150. package/dist/compression-optimizer.d.ts +1 -1
  151. package/dist/config.d.ts +1 -1
  152. package/dist/config.js +4 -2
  153. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  154. package/dist/connectors/codex-materialize-runner.js +12 -10
  155. package/dist/connectors/codex-materialize.d.ts +1 -1
  156. package/dist/connectors/index.d.ts +1 -1
  157. package/dist/connectors/index.js +12 -10
  158. package/dist/consolidation-provenance-check.d.ts +3 -2
  159. package/dist/consolidation-undo.d.ts +3 -2
  160. package/dist/contradiction/index.d.ts +3 -2
  161. package/dist/conversation-index/backend.d.ts +1 -1
  162. package/dist/conversation-index/backend.js +2 -2
  163. package/dist/conversation-index/chunker.d.ts +1 -1
  164. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  165. package/dist/conversation-index/indexer.d.ts +1 -1
  166. package/dist/conversation-index/search.d.ts +1 -1
  167. package/dist/corpus-watermark.d.ts +15 -2
  168. package/dist/corpus-watermark.js +25 -21
  169. package/dist/day-summary.d.ts +1 -1
  170. package/dist/delinearize.d.ts +1 -1
  171. package/dist/direct-answer-wiring.d.ts +1 -1
  172. package/dist/direct-answer.d.ts +1 -1
  173. package/dist/embedding-fallback.d.ts +1 -1
  174. package/dist/enrichment/index.d.ts +1 -1
  175. package/dist/entity-id-normalization.d.ts +4 -0
  176. package/dist/entity-id-normalization.js +10 -0
  177. package/dist/entity-id-normalization.js.map +1 -0
  178. package/dist/entity-retrieval-boundaries.d.ts +3 -0
  179. package/dist/entity-retrieval-boundaries.js +8 -0
  180. package/dist/entity-retrieval-boundaries.js.map +1 -0
  181. package/dist/entity-retrieval.d.ts +3 -2
  182. package/dist/entity-retrieval.js +13 -10
  183. package/dist/entity-schema.d.ts +1 -1
  184. package/dist/entity-schema.js +1 -1
  185. package/dist/explicit-capture.d.ts +9 -8
  186. package/dist/extraction-error-classification.d.ts +1 -1
  187. package/dist/extraction-faithfulness.d.ts +1 -1
  188. package/dist/extraction-judge-telemetry.d.ts +1 -1
  189. package/dist/extraction-judge-training.d.ts +1 -1
  190. package/dist/extraction-judge.d.ts +1 -1
  191. package/dist/extraction-liveness.d.ts +1 -1
  192. package/dist/extraction.d.ts +1 -1
  193. package/dist/fallback-llm.d.ts +1 -1
  194. package/dist/{first-start-migration-LEXL3XYL.js → first-start-migration-BKNGOFED.js} +4 -4
  195. package/dist/graph-dashboard-diff.d.ts +1 -1
  196. package/dist/graph-dashboard-key.d.ts +1 -1
  197. package/dist/graph-dashboard-parser.d.ts +1 -1
  198. package/dist/graph-edge-reinforcement.d.ts +1 -1
  199. package/dist/graph-snapshot.d.ts +1 -1
  200. package/dist/graph.d.ts +1 -1
  201. package/dist/importance.d.ts +1 -1
  202. package/dist/importers/index.d.ts +1 -1
  203. package/dist/in-flight-reads.d.ts +1 -1
  204. package/dist/index.d.ts +409 -407
  205. package/dist/index.js +147 -141
  206. package/dist/intent.d.ts +1 -1
  207. package/dist/lcm/engine.d.ts +1 -1
  208. package/dist/lcm/engine.js +3 -3
  209. package/dist/lcm/index.d.ts +1 -1
  210. package/dist/lcm/index.js +9 -9
  211. package/dist/lcm/tools.d.ts +1 -1
  212. package/dist/lifecycle.d.ts +1 -1
  213. package/dist/live-connectors-runner.d.ts +1 -1
  214. package/dist/local-llm.d.ts +1 -1
  215. package/dist/local-model-endpoint.d.ts +1 -1
  216. package/dist/maintenance/memory-governance.d.ts +1 -1
  217. package/dist/maintenance/memory-governance.js +12 -10
  218. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +3 -2
  219. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +12 -10
  220. package/dist/maintenance/rebuild-memory-projection.d.ts +3 -2
  221. package/dist/maintenance/rebuild-memory-projection.js +13 -11
  222. package/dist/{maintenance-DgnD2z8S.d.ts → maintenance-DveW6azo.d.ts} +3 -3
  223. package/dist/mcp-memory-inspector-app.d.ts +13 -10
  224. package/dist/memory-action-policy.d.ts +1 -1
  225. package/dist/memory-cache.d.ts +1 -1
  226. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  227. package/dist/memory-projection-mutations.d.ts +4 -0
  228. package/dist/memory-projection-mutations.js +15 -0
  229. package/dist/memory-projection-mutations.js.map +1 -0
  230. package/dist/memory-projection-store.d.ts +1 -1
  231. package/dist/memory-provenance.d.ts +1 -1
  232. package/dist/memory-worth-outcomes.d.ts +3 -2
  233. package/dist/models-json.d.ts +1 -1
  234. package/dist/namespaces/migrate.d.ts +4 -3
  235. package/dist/namespaces/migrate.js +22 -20
  236. package/dist/namespaces/principal.d.ts +1 -1
  237. package/dist/namespaces/search.d.ts +1 -1
  238. package/dist/namespaces/search.js +9 -9
  239. package/dist/namespaces/storage.d.ts +4 -3
  240. package/dist/namespaces/storage.js +12 -10
  241. package/dist/native-knowledge.d.ts +1 -1
  242. package/dist/offline-sync-impression-drain.d.ts +1 -1
  243. package/dist/offline-sync-impression-drain.js +3 -3
  244. package/dist/operator-doctor-corpus.d.ts +22 -3
  245. package/dist/operator-doctor-corpus.js +32 -22
  246. package/dist/operator-doctor-replica.d.ts +52 -0
  247. package/dist/operator-doctor-replica.js +15 -0
  248. package/dist/operator-doctor-replica.js.map +1 -0
  249. package/dist/operator-toolkit.d.ts +7 -3
  250. package/dist/operator-toolkit.js +33 -27
  251. package/dist/orchestration/compression-guideline-coordinator.d.ts +3 -2
  252. package/dist/orchestration/maintenance.d.ts +5 -4
  253. package/dist/orchestration/maintenance.js +17 -15
  254. package/dist/{orchestrator-rIHmHpv1.d.ts → orchestrator-Cvlgpe6I.d.ts} +7 -7
  255. package/dist/orchestrator.d.ts +9 -8
  256. package/dist/orchestrator.js +99 -93
  257. package/dist/patterns-cli.d.ts +1 -1
  258. package/dist/{pipeline-Bq5zU6Bp.d.ts → pipeline-BveYVaz7.d.ts} +1 -1
  259. package/dist/policy-runtime.d.ts +1 -1
  260. package/dist/proactive-contention.d.ts +1 -1
  261. package/dist/provenance.d.ts +1 -1
  262. package/dist/{qmd-3ILJkC70.d.ts → qmd-CLWDsbYR.d.ts} +1 -1
  263. package/dist/qmd-preflight.d.ts +2 -2
  264. package/dist/qmd-recall-cache.d.ts +1 -1
  265. package/dist/qmd.d.ts +2 -2
  266. package/dist/recall-concurrency-config.d.ts +1 -1
  267. package/dist/recall-disclosure-escalation.d.ts +1 -1
  268. package/dist/recall-explain-renderer.d.ts +1 -1
  269. package/dist/recall-explain-renderer.js +3 -3
  270. package/dist/recall-memory-map.d.ts +1 -1
  271. package/dist/recall-planner-llm.d.ts +1 -1
  272. package/dist/recall-state.d.ts +1 -1
  273. package/dist/recall-state.js +2 -2
  274. package/dist/recall-tag-filter.d.ts +1 -1
  275. package/dist/recall-timings.d.ts +1 -1
  276. package/dist/recall-xray-cli.d.ts +1 -1
  277. package/dist/recall-xray-cli.js +4 -4
  278. package/dist/recall-xray-renderer.d.ts +1 -1
  279. package/dist/recall-xray-renderer.js +3 -3
  280. package/dist/recall-xray.d.ts +1 -1
  281. package/dist/recall-xray.js +2 -2
  282. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  283. package/dist/replay/normalizers/claude.d.ts +1 -1
  284. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  285. package/dist/replay/normalizers/shared.d.ts +1 -1
  286. package/dist/replay/runner.d.ts +1 -1
  287. package/dist/replay/types.d.ts +1 -1
  288. package/dist/replica-divergence.d.ts +279 -0
  289. package/dist/replica-divergence.js +28 -0
  290. package/dist/replica-divergence.js.map +1 -0
  291. package/dist/replica-peers-config.d.ts +5 -0
  292. package/dist/replica-peers-config.js +13 -0
  293. package/dist/replica-peers-config.js.map +1 -0
  294. package/dist/resolve-auth-token.d.ts +21 -2
  295. package/dist/resolve-auth-token.js +5 -1
  296. package/dist/resume-bundles.js +5 -3
  297. package/dist/retrieval-agents.d.ts +2 -2
  298. package/dist/retrieval-tiers.d.ts +1 -1
  299. package/dist/routing/engine.d.ts +1 -1
  300. package/dist/routing/store.d.ts +1 -1
  301. package/dist/salvage-envelope.d.ts +1 -1
  302. package/dist/schemas.d.ts +76 -76
  303. package/dist/{scope-profiles-D0-ff4xT.d.ts → scope-profiles-BVf3DZ7z.d.ts} +1 -1
  304. package/dist/search/embed-helper.d.ts +1 -1
  305. package/dist/search/factory.d.ts +1 -1
  306. package/dist/search/factory.js +8 -8
  307. package/dist/search/index.d.ts +1 -1
  308. package/dist/search/index.js +13 -13
  309. package/dist/search/lancedb-backend.d.ts +1 -1
  310. package/dist/search/lancedb-backend.js +2 -2
  311. package/dist/search/meilisearch-backend.d.ts +1 -1
  312. package/dist/search/meilisearch-backend.js +2 -2
  313. package/dist/search/noop-backend.d.ts +1 -1
  314. package/dist/search/orama-backend.d.ts +1 -1
  315. package/dist/search/orama-backend.js +2 -2
  316. package/dist/search/port.d.ts +1 -1
  317. package/dist/search/remote-backend.d.ts +1 -1
  318. package/dist/{semantic-consolidation-4Tfh7c1g.d.ts → semantic-consolidation-DXLV47y2.d.ts} +1 -1
  319. package/dist/semantic-consolidation.d.ts +2 -2
  320. package/dist/semantic-consolidation.js +13 -11
  321. package/dist/semantic-rule-promotion.js +12 -10
  322. package/dist/semantic-rule-verifier.d.ts +1 -1
  323. package/dist/semantic-rule-verifier.js +12 -10
  324. package/dist/{service-cTvil7D_.d.ts → service-DbgPTeMJ.d.ts} +2 -2
  325. package/dist/session-observer-bands.d.ts +1 -1
  326. package/dist/session-observer-state.d.ts +1 -1
  327. package/dist/shared-context/manager.d.ts +9 -9
  328. package/dist/signal.d.ts +1 -1
  329. package/dist/{storage-C9ibpTme.d.ts → storage-DOzTm8wG.d.ts} +13 -19
  330. package/dist/storage.d.ts +3 -2
  331. package/dist/storage.js +13 -10
  332. package/dist/summarizer.d.ts +1 -1
  333. package/dist/summary-snapshot.d.ts +1 -1
  334. package/dist/temporal-supersession.d.ts +3 -2
  335. package/dist/temporal-timeline-recall.d.ts +1 -1
  336. package/dist/temporal-validity.d.ts +1 -1
  337. package/dist/threading.d.ts +1 -1
  338. package/dist/tier-migration.d.ts +3 -2
  339. package/dist/tier-routing.d.ts +1 -1
  340. package/dist/topics.d.ts +1 -1
  341. package/dist/transcript.d.ts +1 -1
  342. package/dist/transfer/autodetect.js +1 -1
  343. package/dist/transfer/backup.js +2 -2
  344. package/dist/transfer/capsule-export.js +3 -3
  345. package/dist/transfer/capsule-import.js +2 -2
  346. package/dist/transfer/types.d.ts +66 -66
  347. package/dist/trust-score-stage.d.ts +1 -1
  348. package/dist/trust-score.d.ts +1 -1
  349. package/dist/{types-DHBxIF0s.d.ts → types-BA7W-_xy.d.ts} +53 -4
  350. package/dist/types.d.ts +1 -1
  351. package/dist/types.js +1 -1
  352. package/dist/utility-runtime.d.ts +1 -1
  353. package/dist/verified-recall.js +12 -10
  354. package/dist/write-envelope.d.ts +1 -1
  355. package/package.json +2 -2
  356. package/src/access-health-types.ts +8 -0
  357. package/src/access-http.test.ts +4 -0
  358. package/src/access-service-health.test.ts +23 -0
  359. package/src/access-service.ts +27 -4
  360. package/src/cli.ts +9 -7
  361. package/src/config.ts +2 -1
  362. package/src/corpus-watermark.test.ts +21 -0
  363. package/src/corpus-watermark.ts +25 -3
  364. package/src/entity-id-normalization.ts +55 -0
  365. package/src/entity-retrieval-boundaries.ts +134 -0
  366. package/src/entity-retrieval.ts +253 -27
  367. package/src/entity-schema.ts +2 -1
  368. package/src/memory-projection-mutations.ts +132 -0
  369. package/src/namespaces/storage.ts +5 -3
  370. package/src/operator-doctor-corpus.ts +41 -0
  371. package/src/operator-doctor-replica.test.ts +261 -0
  372. package/src/operator-doctor-replica.ts +129 -0
  373. package/src/operator-toolkit.ts +5 -4
  374. package/src/orchestration/orchestrator-init.ts +2 -2
  375. package/src/replica-divergence.test.ts +1475 -0
  376. package/src/replica-divergence.ts +910 -0
  377. package/src/replica-peers-config.ts +250 -0
  378. package/src/resolve-auth-token.ts +38 -0
  379. package/src/storage/entity-canonical-id-migration-adapter.ts +72 -0
  380. package/src/storage/entity-canonical-id-migration-runner.ts +68 -0
  381. package/src/storage/entity-canonical-id-migration.ts +904 -0
  382. package/src/storage/entity-store.ts +44 -0
  383. package/src/storage/memory-frontmatter-metadata.ts +17 -0
  384. package/src/storage/memory-migration-serialization.ts +37 -0
  385. package/src/storage/memory-read-store.ts +3 -2
  386. package/src/storage/profile-header.ts +8 -7
  387. package/src/storage-profile-timestamp.test.ts +68 -0
  388. package/src/storage.ts +68 -69
  389. package/src/types.ts +3 -3
  390. package/dist/chunk-2RAC4JIG.js.map +0 -1
  391. package/dist/chunk-4DJQYKMN.js.map +0 -1
  392. package/dist/chunk-CIQXI47W.js.map +0 -1
  393. package/dist/chunk-EOLC6EXV.js.map +0 -1
  394. package/dist/chunk-GJJBPI6I.js.map +0 -1
  395. package/dist/chunk-HORJVJ6K.js.map +0 -1
  396. package/dist/chunk-MEBQFQ26.js.map +0 -1
  397. package/dist/chunk-NUWMZIYZ.js.map +0 -1
  398. package/dist/chunk-V25OWXAC.js.map +0 -1
  399. package/dist/chunk-XKO7BM2C.js.map +0 -1
  400. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
  401. /package/dist/{chunk-7RZJWZ46.js.map → chunk-227UFSEQ.js.map} +0 -0
  402. /package/dist/{chunk-UT3OQPFA.js.map → chunk-2BEJ4XCF.js.map} +0 -0
  403. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
  404. /package/dist/{chunk-6NNNURLK.js.map → chunk-2PHX3I5C.js.map} +0 -0
  405. /package/dist/{chunk-RPA2RX5P.js.map → chunk-3BSJBIZ3.js.map} +0 -0
  406. /package/dist/{chunk-JCVQV6QX.js.map → chunk-3UOSVTFR.js.map} +0 -0
  407. /package/dist/{chunk-AJ7QCSIS.js.map → chunk-7CPOZH6Y.js.map} +0 -0
  408. /package/dist/{chunk-U3TH5Q2Q.js.map → chunk-ALTP3MFS.js.map} +0 -0
  409. /package/dist/{chunk-77CNV7DY.js.map → chunk-BLAKS3CP.js.map} +0 -0
  410. /package/dist/{chunk-XQ4EH6DI.js.map → chunk-BR4UFMLO.js.map} +0 -0
  411. /package/dist/{chunk-WEAO45M4.js.map → chunk-DKQM5Q6Q.js.map} +0 -0
  412. /package/dist/{chunk-CSXHRAJJ.js.map → chunk-EG64LXKL.js.map} +0 -0
  413. /package/dist/{chunk-PTN6UAUA.js.map → chunk-ES36HTSC.js.map} +0 -0
  414. /package/dist/{chunk-5BRT4Z2I.js.map → chunk-EZWWCN7I.js.map} +0 -0
  415. /package/dist/{chunk-XKGPIWGI.js.map → chunk-FBZTWUK5.js.map} +0 -0
  416. /package/dist/{chunk-FRVTCCGD.js.map → chunk-GJPCP5CA.js.map} +0 -0
  417. /package/dist/{chunk-VDX2J7OX.js.map → chunk-IPLYGWQF.js.map} +0 -0
  418. /package/dist/{chunk-YSGBD3QN.js.map → chunk-IYT632D5.js.map} +0 -0
  419. /package/dist/{chunk-2QSZNTDO.js.map → chunk-JBPKEARU.js.map} +0 -0
  420. /package/dist/{chunk-RSYJV25N.js.map → chunk-JIF3VRKQ.js.map} +0 -0
  421. /package/dist/{chunk-EUSLKI4X.js.map → chunk-KKBTBUVT.js.map} +0 -0
  422. /package/dist/{chunk-RNY3BO35.js.map → chunk-LIHC3T43.js.map} +0 -0
  423. /package/dist/{chunk-UGH6VPPO.js.map → chunk-MWTMTW2T.js.map} +0 -0
  424. /package/dist/{chunk-MG6MNSP4.js.map → chunk-MXJ3VP6S.js.map} +0 -0
  425. /package/dist/{chunk-M5EPMNS4.js.map → chunk-P2CLYN6H.js.map} +0 -0
  426. /package/dist/{chunk-KGTD2KZJ.js.map → chunk-Q6YJW6KE.js.map} +0 -0
  427. /package/dist/{chunk-X3SQYAPP.js.map → chunk-R372P2EH.js.map} +0 -0
  428. /package/dist/{chunk-4MJZTF42.js.map → chunk-RKXZ7P4V.js.map} +0 -0
  429. /package/dist/{chunk-RYHWZ52A.js.map → chunk-S2BBISHU.js.map} +0 -0
  430. /package/dist/{chunk-LLISELSY.js.map → chunk-TBMRQZDY.js.map} +0 -0
  431. /package/dist/{chunk-FMLKOL2Z.js.map → chunk-TC3VNKGX.js.map} +0 -0
  432. /package/dist/{chunk-7K5Q6COX.js.map → chunk-TVVEYCNW.js.map} +0 -0
  433. /package/dist/{chunk-JDOJZTFF.js.map → chunk-VFNI3RPT.js.map} +0 -0
  434. /package/dist/{chunk-EYJSW2RV.js.map → chunk-VYYNBJXH.js.map} +0 -0
  435. /package/dist/{chunk-BHLN7L7M.js.map → chunk-WVVK2RFM.js.map} +0 -0
  436. /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
  437. /package/dist/{chunk-HEXSNYJD.js.map → chunk-YOBNCD3Z.js.map} +0 -0
  438. /package/dist/{chunk-SK3EYPKC.js.map → chunk-ZN4UZWMT.js.map} +0 -0
  439. /package/dist/{first-start-migration-LEXL3XYL.js.map → first-start-migration-BKNGOFED.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  StorageManager
3
- } from "./chunk-CIQXI47W.js";
3
+ } from "./chunk-Q5VJUNXA.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-JDOJZTFF.js.map
122
+ //# sourceMappingURL=chunk-VFNI3RPT.js.map
@@ -0,0 +1,134 @@
1
+ // src/entity-retrieval-boundaries.ts
2
+ var UNICODE_WORD_OR_NUMBER_RE = /[\p{L}\p{M}\p{N}]/u;
3
+ function firstUnicodeCharacter(value) {
4
+ const codePoint = value.codePointAt(0);
5
+ return codePoint === void 0 ? "" : String.fromCodePoint(codePoint);
6
+ }
7
+ function lastUnicodeCharacter(value) {
8
+ const codePoint = [...value].at(-1);
9
+ return codePoint ?? "";
10
+ }
11
+ var JAPANESE_PARTICLE_RE = /^[のはがをにへともやかでだ]$/u;
12
+ var JAPANESE_MULTI_CHARACTER_PARTICLES = [
13
+ "\u306B\u3064\u3044\u3066",
14
+ "\u306B\u3068\u3063\u3066",
15
+ "\u306B\u3088\u3063\u3066",
16
+ "\u306B\u95A2\u3057\u3066",
17
+ "\u306B\u5BFE\u3057\u3066",
18
+ "\u3068\u306F",
19
+ "\u3067\u306F",
20
+ "\u306B\u306F",
21
+ "\u306B\u3082",
22
+ "\u3063\u3066"
23
+ ];
24
+ var KOREAN_PARTICLES = [
25
+ "\uC5D0\uC11C",
26
+ "\uC5D0\uAC8C",
27
+ "\uD55C\uD14C",
28
+ "\uC73C\uB85C",
29
+ "\uAE4C\uC9C0",
30
+ "\uBD80\uD130",
31
+ "\uBCF4\uB2E4",
32
+ "\uCC98\uB7FC",
33
+ "\uAC19\uC774",
34
+ "\uC774\uB098",
35
+ "\uB77C\uB3C4",
36
+ "\uBC16\uC5D0",
37
+ "\uB9C8\uB2E4",
38
+ "\uC870\uCC28",
39
+ "\uC774\uB791",
40
+ "\uD558\uACE0",
41
+ "\uC740",
42
+ "\uB294",
43
+ "\uC774",
44
+ "\uAC00",
45
+ "\uC744",
46
+ "\uB97C",
47
+ "\uC758",
48
+ "\uAED8",
49
+ "\uC640",
50
+ "\uACFC",
51
+ "\uB3C4",
52
+ "\uB9CC",
53
+ "\uB4E0",
54
+ "\uC5D0",
55
+ "\uB85C",
56
+ "\uB098",
57
+ "\uB791"
58
+ ];
59
+ var KOREAN_UNSPACED_QUESTION_PARTICLES = ["\uC740", "\uB294", "\uC774", "\uAC00"];
60
+ var KOREAN_INTERROGATIVE_PREFIXES = [
61
+ "\uC5B4\uB514",
62
+ "\uBB34\uC5C7",
63
+ "\uBB50",
64
+ "\uC65C",
65
+ "\uC5B4\uB5BB\uAC8C",
66
+ "\uC5B8\uC81C",
67
+ "\uB204\uAD6C",
68
+ "\uC5B4\uB290",
69
+ "\uBA87",
70
+ "\uC5BC\uB9C8"
71
+ ];
72
+ var HANGUL_RUN_RE = /^[\p{Script=Hangul}]+/u;
73
+ var UNICODE_WORD_SEGMENTER = typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "word" }) : null;
74
+ var KOREAN_WORD_SEGMENTER = typeof Intl.Segmenter === "function" ? new Intl.Segmenter("ko", { granularity: "word" }) : null;
75
+ var JAPANESE_WORD_SEGMENTER = typeof Intl.Segmenter === "function" ? new Intl.Segmenter("ja", { granularity: "word" }) : null;
76
+ var JAPANESE_KANA_RE = /[\p{Script=Hiragana}\p{Script=Katakana}]/u;
77
+ function isJapaneseParticleBoundary(suffix) {
78
+ const firstSegment = JAPANESE_WORD_SEGMENTER?.segment(suffix).containing(0)?.segment;
79
+ if (firstSegment !== void 0) {
80
+ if (JAPANESE_MULTI_CHARACTER_PARTICLES.some((particle) => particle === firstSegment)) return true;
81
+ return JAPANESE_PARTICLE_RE.test(firstSegment);
82
+ }
83
+ const firstCharacter = firstUnicodeCharacter(suffix);
84
+ return JAPANESE_MULTI_CHARACTER_PARTICLES.some((particle) => suffix.startsWith(particle)) || JAPANESE_PARTICLE_RE.test(firstCharacter) && !UNICODE_WORD_OR_NUMBER_RE.test(firstUnicodeCharacter(suffix.slice(firstCharacter.length)));
85
+ }
86
+ function isIntlWordBoundary(source, index) {
87
+ if (index <= 0 || index >= source.length) return true;
88
+ return UNICODE_WORD_SEGMENTER?.segment(source).containing(index)?.index === index;
89
+ }
90
+ function isKoreanUnspacedQuestionBoundary(suffix) {
91
+ return KOREAN_UNSPACED_QUESTION_PARTICLES.some(
92
+ (particle) => suffix.startsWith(particle) && KOREAN_INTERROGATIVE_PREFIXES.some((prefix) => suffix.startsWith(prefix, particle.length))
93
+ );
94
+ }
95
+ function isKoreanParticleBoundary(suffix) {
96
+ if (isKoreanUnspacedQuestionBoundary(suffix)) return true;
97
+ const firstSegment = KOREAN_WORD_SEGMENTER?.segment(suffix).containing(0)?.segment;
98
+ if (firstSegment !== void 0) {
99
+ return KOREAN_PARTICLES.some((particle) => particle === firstSegment);
100
+ }
101
+ const particleRun = suffix.match(HANGUL_RUN_RE)?.[0] ?? "";
102
+ const nextCharacter = firstUnicodeCharacter(suffix.slice(particleRun.length));
103
+ return KOREAN_PARTICLES.some((particle) => particle === particleRun) && (nextCharacter.length === 0 || !UNICODE_WORD_OR_NUMBER_RE.test(nextCharacter));
104
+ }
105
+ function isUnicodePhraseBoundary(character, suffix = "", source = "", boundaryIndex = -1, strictUnicode = false, allowLeadingParticle = false) {
106
+ return character.length === 0 || !UNICODE_WORD_OR_NUMBER_RE.test(character) || allowLeadingParticle && isJapaneseParticleBoundary(character) || isJapaneseParticleBoundary(suffix) || !strictUnicode && boundaryIndex >= 0 && !JAPANESE_KANA_RE.test(suffix) && isIntlWordBoundary(source, boundaryIndex) || allowLeadingParticle && isKoreanParticleBoundary(character) || isKoreanParticleBoundary(suffix);
107
+ }
108
+ function containsPhrase(haystack, needle) {
109
+ if (!needle) return false;
110
+ const caseInsensitive = /^[a-z0-9 ]+$/i.test(needle);
111
+ const searchHaystack = caseInsensitive ? haystack.toLowerCase() : haystack;
112
+ const searchNeedle = caseInsensitive ? needle.toLowerCase() : needle;
113
+ let offset = searchHaystack.indexOf(searchNeedle);
114
+ while (offset >= 0) {
115
+ const before = lastUnicodeCharacter(searchHaystack.slice(0, offset));
116
+ const after = searchHaystack.slice(offset + searchNeedle.length);
117
+ if (isUnicodePhraseBoundary(before, "", searchHaystack, offset, caseInsensitive, true) && isUnicodePhraseBoundary(
118
+ firstUnicodeCharacter(after),
119
+ after,
120
+ searchHaystack,
121
+ offset + searchNeedle.length,
122
+ caseInsensitive
123
+ )) {
124
+ return true;
125
+ }
126
+ offset = searchHaystack.indexOf(searchNeedle, offset + searchNeedle.length);
127
+ }
128
+ return false;
129
+ }
130
+
131
+ export {
132
+ containsPhrase
133
+ };
134
+ //# sourceMappingURL=chunk-VNA7W7QF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entity-retrieval-boundaries.ts"],"sourcesContent":["const UNICODE_WORD_OR_NUMBER_RE = /[\\p{L}\\p{M}\\p{N}]/u;\n\nfunction firstUnicodeCharacter(value: string): string {\n const codePoint = value.codePointAt(0);\n return codePoint === undefined ? \"\" : String.fromCodePoint(codePoint);\n}\n\nfunction lastUnicodeCharacter(value: string): string {\n const codePoint = [...value].at(-1);\n return codePoint ?? \"\";\n}\n\nconst JAPANESE_PARTICLE_RE = /^[のはがをにへともやかでだ]$/u;\nconst JAPANESE_MULTI_CHARACTER_PARTICLES = [\n \"について\",\n \"にとって\",\n \"によって\",\n \"に関して\",\n \"に対して\",\n \"とは\",\n \"では\",\n \"には\",\n \"にも\",\n \"って\",\n] as const;\nconst KOREAN_PARTICLES = [\n \"에서\", \"에게\", \"한테\", \"으로\", \"까지\", \"부터\", \"보다\", \"처럼\", \"같이\",\n \"이나\", \"라도\", \"밖에\", \"마다\", \"조차\", \"이랑\", \"하고\", \"은\", \"는\",\n \"이\", \"가\", \"을\", \"를\", \"의\", \"께\", \"와\", \"과\", \"도\", \"만\", \"든\",\n \"에\", \"로\", \"나\", \"랑\",\n] as const;\nconst KOREAN_UNSPACED_QUESTION_PARTICLES = [\"은\", \"는\", \"이\", \"가\"] as const;\nconst KOREAN_INTERROGATIVE_PREFIXES = [\n \"어디\", \"무엇\", \"뭐\", \"왜\", \"어떻게\", \"언제\", \"누구\", \"어느\", \"몇\", \"얼마\",\n] as const;\n\nconst HANGUL_RUN_RE = /^[\\p{Script=Hangul}]+/u;\n\nconst UNICODE_WORD_SEGMENTER =\n typeof Intl.Segmenter === \"function\" ? new Intl.Segmenter(undefined, { granularity: \"word\" }) : null;\nconst KOREAN_WORD_SEGMENTER =\n typeof Intl.Segmenter === \"function\" ? new Intl.Segmenter(\"ko\", { granularity: \"word\" }) : null;\n\nconst JAPANESE_WORD_SEGMENTER =\n typeof Intl.Segmenter === \"function\" ? new Intl.Segmenter(\"ja\", { granularity: \"word\" }) : null;\nconst JAPANESE_KANA_RE = /[\\p{Script=Hiragana}\\p{Script=Katakana}]/u;\n\nfunction isJapaneseParticleBoundary(suffix: string): boolean {\n const firstSegment = JAPANESE_WORD_SEGMENTER?.segment(suffix).containing(0)?.segment;\n if (firstSegment !== undefined) {\n if (JAPANESE_MULTI_CHARACTER_PARTICLES.some((particle) => particle === firstSegment)) return true;\n return JAPANESE_PARTICLE_RE.test(firstSegment);\n }\n const firstCharacter = firstUnicodeCharacter(suffix);\n return (\n JAPANESE_MULTI_CHARACTER_PARTICLES.some((particle) => suffix.startsWith(particle)) ||\n (JAPANESE_PARTICLE_RE.test(firstCharacter) &&\n !UNICODE_WORD_OR_NUMBER_RE.test(firstUnicodeCharacter(suffix.slice(firstCharacter.length))))\n );\n}\n\nfunction isIntlWordBoundary(source: string, index: number): boolean {\n if (index <= 0 || index >= source.length) return true;\n return UNICODE_WORD_SEGMENTER?.segment(source).containing(index)?.index === index;\n}\n\nfunction isKoreanUnspacedQuestionBoundary(suffix: string): boolean {\n return KOREAN_UNSPACED_QUESTION_PARTICLES.some((particle) =>\n suffix.startsWith(particle) &&\n KOREAN_INTERROGATIVE_PREFIXES.some((prefix) => suffix.startsWith(prefix, particle.length)),\n );\n}\n\nfunction isKoreanParticleBoundary(suffix: string): boolean {\n if (isKoreanUnspacedQuestionBoundary(suffix)) return true;\n const firstSegment = KOREAN_WORD_SEGMENTER?.segment(suffix).containing(0)?.segment;\n if (firstSegment !== undefined) {\n return KOREAN_PARTICLES.some((particle) => particle === firstSegment);\n }\n const particleRun = suffix.match(HANGUL_RUN_RE)?.[0] ?? \"\";\n const nextCharacter = firstUnicodeCharacter(suffix.slice(particleRun.length));\n return (\n KOREAN_PARTICLES.some((particle) => particle === particleRun) &&\n (nextCharacter.length === 0 || !UNICODE_WORD_OR_NUMBER_RE.test(nextCharacter))\n );\n}\n\nfunction isUnicodePhraseBoundary(\n character: string,\n suffix: string = \"\",\n source: string = \"\",\n boundaryIndex: number = -1,\n strictUnicode = false,\n allowLeadingParticle = false,\n): boolean {\n return (\n character.length === 0\n || !UNICODE_WORD_OR_NUMBER_RE.test(character)\n || (allowLeadingParticle && isJapaneseParticleBoundary(character))\n || isJapaneseParticleBoundary(suffix)\n || (!strictUnicode &&\n boundaryIndex >= 0 &&\n !JAPANESE_KANA_RE.test(suffix) &&\n isIntlWordBoundary(source, boundaryIndex))\n || (allowLeadingParticle && isKoreanParticleBoundary(character))\n || isKoreanParticleBoundary(suffix)\n );\n}\n\nexport function containsPhrase(haystack: string, needle: string): boolean {\n if (!needle) return false;\n const caseInsensitive = /^[a-z0-9 ]+$/i.test(needle);\n const searchHaystack = caseInsensitive ? haystack.toLowerCase() : haystack;\n const searchNeedle = caseInsensitive ? needle.toLowerCase() : needle;\n let offset = searchHaystack.indexOf(searchNeedle);\n while (offset >= 0) {\n const before = lastUnicodeCharacter(searchHaystack.slice(0, offset));\n const after = searchHaystack.slice(offset + searchNeedle.length);\n if (\n isUnicodePhraseBoundary(before, \"\", searchHaystack, offset, caseInsensitive, true)\n && isUnicodePhraseBoundary(\n firstUnicodeCharacter(after),\n after,\n searchHaystack,\n offset + searchNeedle.length,\n caseInsensitive,\n )\n ) {\n return true;\n }\n offset = searchHaystack.indexOf(searchNeedle, offset + searchNeedle.length);\n }\n return false;\n}\n"],"mappings":"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","names":[]}
@@ -1,9 +1,9 @@
1
- import {
2
- namespaceCollectionName
3
- } from "./chunk-SK3EYPKC.js";
4
1
  import {
5
2
  NamespaceStorageRouter
6
- } from "./chunk-MEBQFQ26.js";
3
+ } from "./chunk-AHFZXUZM.js";
4
+ import {
5
+ namespaceCollectionName
6
+ } from "./chunk-ZN4UZWMT.js";
7
7
  import {
8
8
  namespaceIdentityFromToken,
9
9
  namespaceIdentityToken
@@ -207,4 +207,4 @@ export {
207
207
  verifyNamespaces,
208
208
  runNamespaceMigration
209
209
  };
210
- //# sourceMappingURL=chunk-EYJSW2RV.js.map
210
+ //# sourceMappingURL=chunk-VYYNBJXH.js.map
@@ -0,0 +1,152 @@
1
+ import {
2
+ isAgentAccessSecretRef
3
+ } from "./chunk-IJ6WHMFB.js";
4
+ import {
5
+ coerceBool,
6
+ coerceNumber
7
+ } from "./chunk-PQVCH2AE.js";
8
+
9
+ // src/replica-peers-config.ts
10
+ var DEFAULT_POLL_INTERVAL_MS = 3e5;
11
+ var DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
12
+ var DEFAULT_MAX_FILE_COUNT_DELTA = 100;
13
+ var DEFAULT_MAX_WATERMARK_AGE_DELTA_MS = 9e5;
14
+ var MAX_TIMER_DELAY_MS = 2147483647;
15
+ function expandEnvValue(value) {
16
+ const resolved = value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match, name) => {
17
+ const envValue = process.env[name];
18
+ if (envValue === void 0 || envValue === "") {
19
+ throw new Error(`replicaPeers: environment variable ${name} is not set`);
20
+ }
21
+ return envValue;
22
+ });
23
+ const unterminated = resolved.match(/\$\{[^}]*$/);
24
+ if (unterminated) {
25
+ throw new Error(`replicaPeers: unterminated environment variable placeholder: ${unterminated[0]}`);
26
+ }
27
+ const remaining = resolved.match(/\$\{[^}]*\}/);
28
+ if (remaining) {
29
+ throw new Error(`replicaPeers: malformed environment variable placeholder: ${remaining[0]}`);
30
+ }
31
+ return resolved;
32
+ }
33
+ function parseIntegerAtLeast(value, min, dflt, label, max = Number.MAX_SAFE_INTEGER) {
34
+ if (value === void 0) return dflt;
35
+ const coerced = coerceNumber(value);
36
+ if (coerced === void 0 || !Number.isFinite(coerced) || !Number.isInteger(coerced) || coerced < min) {
37
+ throw new Error(`${label} must be an integer greater than or equal to ${min}; got ${JSON.stringify(value)}`);
38
+ }
39
+ if (coerced > max) {
40
+ throw new Error(`${label} must be an integer no greater than ${max}; got ${JSON.stringify(value)}`);
41
+ }
42
+ return coerced;
43
+ }
44
+ function asRecord(value, label) {
45
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
46
+ throw new Error(`${label} must be an object`);
47
+ }
48
+ return value;
49
+ }
50
+ function parseReplicaPeerToken(raw, index) {
51
+ if (raw === void 0) return void 0;
52
+ if (typeof raw === "string") {
53
+ const trimmed = raw.trim();
54
+ if (trimmed.length === 0) {
55
+ throw new Error(`replicaPeers.peers[${index}].token must be a non-empty string or a SecretRef object`);
56
+ }
57
+ const expanded = expandEnvValue(trimmed);
58
+ if (expanded.trim().length === 0) {
59
+ throw new Error(`replicaPeers.peers[${index}].token expanded to an empty value`);
60
+ }
61
+ return expanded;
62
+ }
63
+ if (isAgentAccessSecretRef(raw)) return raw;
64
+ throw new Error(`replicaPeers.peers[${index}].token must be a string or a SecretRef object`);
65
+ }
66
+ function parseReplicaPeer(value, index) {
67
+ const record = asRecord(value, `replicaPeers.peers[${index}]`);
68
+ if (typeof record.url !== "string" || record.url.trim().length === 0) {
69
+ throw new Error(`replicaPeers.peers[${index}].url must be a non-empty string`);
70
+ }
71
+ const url = expandEnvValue(record.url.trim());
72
+ let parsed;
73
+ try {
74
+ parsed = new URL(url);
75
+ } catch {
76
+ throw new Error(`replicaPeers.peers[${index}].url is not a valid URL`);
77
+ }
78
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
79
+ throw new Error(`replicaPeers.peers[${index}].url must be an http(s) URL (got ${parsed.protocol})`);
80
+ }
81
+ if (parsed.search.length > 0 || parsed.hash.length > 0 || parsed.username.length > 0 || parsed.password.length > 0) {
82
+ throw new Error(`replicaPeers.peers[${index}].url must be a clean base URL (no query, fragment, or embedded credentials)`);
83
+ }
84
+ const token = parseReplicaPeerToken(record.token, index);
85
+ const canonical = parsed.toString().replace(/\/+$/, "");
86
+ return token === void 0 ? { url: canonical } : { url: canonical, token };
87
+ }
88
+ function parseStrictBool(value, fallback, label) {
89
+ if (value === void 0) return fallback;
90
+ const coerced = coerceBool(value);
91
+ if (coerced === void 0) {
92
+ throw new Error(`${label} must be a boolean (got ${JSON.stringify(value)})`);
93
+ }
94
+ return coerced;
95
+ }
96
+ function parseReplicaPeersConfig(cfg) {
97
+ const raw = cfg.replicaPeers;
98
+ if (raw !== void 0 && (raw === null || typeof raw !== "object" || Array.isArray(raw))) {
99
+ throw new Error(`replicaPeers must be a plain object (got ${JSON.stringify(raw)})`);
100
+ }
101
+ const block = raw ?? {};
102
+ if (block.peers !== void 0 && !Array.isArray(block.peers)) {
103
+ throw new Error(`replicaPeers.peers must be an array (got ${JSON.stringify(block.peers)})`);
104
+ }
105
+ const peers = (block.peers ?? []).map(parseReplicaPeer);
106
+ return {
107
+ enabled: parseStrictBool(block.enabled, false, "replicaPeers.enabled"),
108
+ peers,
109
+ pollIntervalMs: parseIntegerAtLeast(block.pollIntervalMs, 1, DEFAULT_POLL_INTERVAL_MS, "replicaPeers.pollIntervalMs"),
110
+ requestTimeoutMs: parseIntegerAtLeast(block.requestTimeoutMs, 1, DEFAULT_REQUEST_TIMEOUT_MS, "replicaPeers.requestTimeoutMs", MAX_TIMER_DELAY_MS),
111
+ maxFileCountDelta: parseIntegerAtLeast(block.maxFileCountDelta, 0, DEFAULT_MAX_FILE_COUNT_DELTA, "replicaPeers.maxFileCountDelta"),
112
+ maxWatermarkAgeDeltaMs: parseIntegerAtLeast(
113
+ block.maxWatermarkAgeDeltaMs,
114
+ 0,
115
+ DEFAULT_MAX_WATERMARK_AGE_DELTA_MS,
116
+ "replicaPeers.maxWatermarkAgeDeltaMs"
117
+ )
118
+ };
119
+ }
120
+ function resolveReplicaPeersConfig(block) {
121
+ const record = block !== null && typeof block === "object" && !Array.isArray(block) ? block : {};
122
+ return {
123
+ enabled: coerceBool(record.enabled) ?? false,
124
+ peers: resolveReplicaPeers(record.peers),
125
+ pollIntervalMs: resolveIntegerAtLeast(record.pollIntervalMs, 1, DEFAULT_POLL_INTERVAL_MS),
126
+ requestTimeoutMs: resolveIntegerAtLeast(record.requestTimeoutMs, 1, DEFAULT_REQUEST_TIMEOUT_MS, MAX_TIMER_DELAY_MS),
127
+ maxFileCountDelta: resolveIntegerAtLeast(record.maxFileCountDelta, 0, DEFAULT_MAX_FILE_COUNT_DELTA),
128
+ maxWatermarkAgeDeltaMs: resolveIntegerAtLeast(record.maxWatermarkAgeDeltaMs, 0, DEFAULT_MAX_WATERMARK_AGE_DELTA_MS)
129
+ };
130
+ }
131
+ function resolveIntegerAtLeast(value, min, dflt, max = Number.MAX_SAFE_INTEGER) {
132
+ if (value === void 0) return dflt;
133
+ const coerced = coerceNumber(value);
134
+ return coerced !== void 0 && Number.isFinite(coerced) && Number.isInteger(coerced) && coerced >= min && coerced <= max ? coerced : dflt;
135
+ }
136
+ function resolveReplicaPeers(value) {
137
+ if (!Array.isArray(value)) return [];
138
+ const peers = [];
139
+ value.forEach((entry, index) => {
140
+ try {
141
+ peers.push(parseReplicaPeer(entry, index));
142
+ } catch {
143
+ }
144
+ });
145
+ return peers;
146
+ }
147
+
148
+ export {
149
+ parseReplicaPeersConfig,
150
+ resolveReplicaPeersConfig
151
+ };
152
+ //# sourceMappingURL=chunk-WNIUPHWV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/replica-peers-config.ts"],"sourcesContent":["/**\n * `replicaPeers` config surface (issue #2149) — types + parser.\n *\n * Deliberately split out of replica-divergence.ts as a LIGHT module: it imports\n * no heavy modules (no corpus-watermark, no access-token-capabilities). PluginConfig\n * carries `replicaPeers: ReplicaPeersConfig`, so types.ts imports ReplicaPeersConfig\n * from HERE. If that type instead lived in replica-divergence.ts (which pulls in the\n * corpus census graph), then types.ts -> replica-divergence.ts -> corpus-watermark.ts\n * -> types.ts would form a heavy import cycle that rollup-plugin-dts re-expands across\n * every PluginConfig-inlining entry, OOMing the default-heap DTS worker (the issue\n * #1562 heap cliff). Keeping the config surface corpus-free severs that cycle.\n */\n\nimport { coerceBool, coerceNumber } from \"./connectors/coerce.js\";\nimport { isAgentAccessSecretRef } from \"./resolve-auth-token.js\";\nimport type { AgentAccessAuthToken } from \"./types.js\";\n\nconst DEFAULT_POLL_INTERVAL_MS = 300_000; // 5 min\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10_000;\nconst DEFAULT_MAX_FILE_COUNT_DELTA = 100;\nconst DEFAULT_MAX_WATERMARK_AGE_DELTA_MS = 900_000; // 15 min\n/** Node clamps a `setTimeout`/`AbortSignal.timeout` delay above 2^31-1 ms to 1ms,\n * which would make `withDeadline` fire immediately and mark every peer unreachable. */\nconst MAX_TIMER_DELAY_MS = 2_147_483_647;\n\nexport interface ReplicaPeerConfig {\n /** Base URL of the peer's agent-access HTTP server (http/https). */\n url: string;\n /**\n * Bearer token for the peer's authenticated `/health`. A literal string\n * (env-expanded) or an unresolved SecretRef preserved verbatim and resolved\n * at poll time — mirrors `agentAccessHttp.authToken` exactly.\n */\n token?: AgentAccessAuthToken;\n}\n\nexport interface ReplicaPeersConfig {\n /** Master gate. Default false — a daemon with no peers behaves exactly as before. */\n enabled: boolean;\n /** Peers to poll. Default []. */\n peers: ReplicaPeerConfig[];\n /** How often a peer is re-polled (SWR TTL), ms. Default 5 min. */\n pollIntervalMs: number;\n /** Per-peer request timeout, ms. Default 10s. */\n requestTimeoutMs: number;\n /** File-count delta (per namespace) beyond which a peer is flagged diverged. Default 100. */\n maxFileCountDelta: number;\n /** Newest-write timestamp gap (per namespace) beyond which a peer is flagged diverged, ms. Default 15 min. */\n maxWatermarkAgeDeltaMs: number;\n}\n\n/**\n * Expand `${ENV_VAR}` placeholders in a config string, matching config.ts's\n * `resolveEnvVars` semantics (throw on unset var / malformed placeholder).\n * Inlined rather than imported because config.ts imports THIS module for\n * `parseReplicaPeersConfig`, so importing back would be circular — the same\n * reason extraction-liveness.ts inlines its numeric validation.\n */\nfunction expandEnvValue(value: string): string {\n const resolved = value.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_match, name: string) => {\n const envValue = process.env[name];\n if (envValue === undefined || envValue === \"\") {\n throw new Error(`replicaPeers: environment variable ${name} is not set`);\n }\n return envValue;\n });\n // An UNTERMINATED `${NAME` matches neither the replacement regex nor the\n // balanced leftover check below, so the literal typo would be sent as the\n // bearer token and surface as a misleading `http_401` (round 8, codex P2).\n const unterminated = resolved.match(/\\$\\{[^}]*$/);\n if (unterminated) {\n throw new Error(`replicaPeers: unterminated environment variable placeholder: ${unterminated[0]}`);\n }\n const remaining = resolved.match(/\\$\\{[^}]*\\}/);\n if (remaining) {\n throw new Error(`replicaPeers: malformed environment variable placeholder: ${remaining[0]}`);\n }\n return resolved;\n}\n\n/**\n * An absent key falls back to the default; any PRESENT value (including an\n * explicit `null`) must coerce to an integer `>= min`, else THROW. A fractional\n * or out-of-range value is rejected, never floored/reinterpreted (§1/§17/§39).\n */\nfunction parseIntegerAtLeast(value: unknown, min: number, dflt: number, label: string, max = Number.MAX_SAFE_INTEGER): number {\n if (value === undefined) return dflt;\n const coerced = coerceNumber(value);\n if (coerced === undefined || !Number.isFinite(coerced) || !Number.isInteger(coerced) || coerced < min) {\n throw new Error(`${label} must be an integer greater than or equal to ${min}; got ${JSON.stringify(value)}`);\n }\n if (coerced > max) {\n throw new Error(`${label} must be an integer no greater than ${max}; got ${JSON.stringify(value)}`);\n }\n return coerced;\n}\n\nfunction asRecord(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(`${label} must be an object`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction parseReplicaPeerToken(raw: unknown, index: number): AgentAccessAuthToken | undefined {\n // Only an OMITTED token selects unauthenticated polling. A present `null` (round\n // 4, codex P2) or an explicit empty/whitespace string (round 6, codex P2) is a\n // present-but-invalid credential: silently dropping it polls without the token\n // and surfaces a healthy peer as `http_401`, hiding the real config error.\n if (raw === undefined) return undefined;\n if (typeof raw === \"string\") {\n const trimmed = raw.trim();\n if (trimmed.length === 0) {\n throw new Error(`replicaPeers.peers[${index}].token must be a non-empty string or a SecretRef object`);\n }\n // Re-validate AFTER expansion: `${PEER_TOKEN}` pointing at a whitespace-only\n // env value clears the check above, then resolveAgentAccessAuthToken\n // normalizes it to undefined — silently downgrading an explicitly\n // authenticated peer to an unauthenticated poll read as http_401 (round 9).\n const expanded = expandEnvValue(trimmed);\n if (expanded.trim().length === 0) {\n throw new Error(`replicaPeers.peers[${index}].token expanded to an empty value`);\n }\n return expanded;\n }\n if (isAgentAccessSecretRef(raw)) return raw;\n throw new Error(`replicaPeers.peers[${index}].token must be a string or a SecretRef object`);\n}\n\nfunction parseReplicaPeer(value: unknown, index: number): ReplicaPeerConfig {\n const record = asRecord(value, `replicaPeers.peers[${index}]`);\n if (typeof record.url !== \"string\" || record.url.trim().length === 0) {\n throw new Error(`replicaPeers.peers[${index}].url must be a non-empty string`);\n }\n const url = expandEnvValue(record.url.trim());\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new Error(`replicaPeers.peers[${index}].url is not a valid URL`);\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n throw new Error(`replicaPeers.peers[${index}].url must be an http(s) URL (got ${parsed.protocol})`);\n }\n // The health path is appended to this base by string concatenation, so a query\n // or fragment would corrupt the request URL (`https://h?x` + `/engram/v1/health`\n // targets `/` with a mangled query; a fragment drops the path). Reject them at\n // parse time — a peer URL must be a clean base (round 6, codex). Embedded\n // credentials (`user:pass@host`) are rejected too: Node's fetch refuses to\n // construct a request from a URL with credentials, so a healthy peer would\n // falsely read as unreachable while redaction hid the config mistake.\n if (parsed.search.length > 0 || parsed.hash.length > 0 || parsed.username.length > 0 || parsed.password.length > 0) {\n throw new Error(`replicaPeers.peers[${index}].url must be a clean base URL (no query, fragment, or embedded credentials)`);\n }\n const token = parseReplicaPeerToken(record.token, index);\n // Store the CANONICAL form: `new URL()` tolerates surrounding whitespace that\n // the raw string keeps, and the health path is appended by concatenation - so\n // \" https://peer /engram/v1/health\" reads as an unreachable healthy peer.\n const canonical = parsed.toString().replace(/\\/+$/, \"\");\n return token === undefined ? { url: canonical } : { url: canonical, token };\n}\n\n/**\n * Parse the `replicaPeers` config block. Mirrors the nested-block validation of\n * the other config-block parsers; coerces string booleans (§24) and rejects\n * invalid numbers/urls/shapes (§1/§39).\n */\n/**\n * Strict boolean for the parse path: absent -> the default, present -> must be\n * a recognized boolean token. A value like `1` must NOT silently reinterpret as\n * `false`, which would leave monitoring off after an operator tried to enable\n * it (round 3, codex P2). The lenient read-boundary resolver still defaults.\n */\nfunction parseStrictBool(value: unknown, fallback: boolean, label: string): boolean {\n if (value === undefined) return fallback;\n const coerced = coerceBool(value);\n if (coerced === undefined) {\n throw new Error(`${label} must be a boolean (got ${JSON.stringify(value)})`);\n }\n return coerced;\n}\n\nexport function parseReplicaPeersConfig(cfg: Record<string, unknown>): ReplicaPeersConfig {\n const raw = cfg.replicaPeers;\n if (raw !== undefined && (raw === null || typeof raw !== \"object\" || Array.isArray(raw))) {\n throw new Error(`replicaPeers must be a plain object (got ${JSON.stringify(raw)})`);\n }\n const block = (raw ?? {}) as Record<string, unknown>;\n if (block.peers !== undefined && !Array.isArray(block.peers)) {\n throw new Error(`replicaPeers.peers must be an array (got ${JSON.stringify(block.peers)})`);\n }\n const peers = (block.peers ?? []).map(parseReplicaPeer);\n return {\n enabled: parseStrictBool(block.enabled, false, \"replicaPeers.enabled\"),\n peers,\n pollIntervalMs: parseIntegerAtLeast(block.pollIntervalMs, 1, DEFAULT_POLL_INTERVAL_MS, \"replicaPeers.pollIntervalMs\"),\n requestTimeoutMs: parseIntegerAtLeast(block.requestTimeoutMs, 1, DEFAULT_REQUEST_TIMEOUT_MS, \"replicaPeers.requestTimeoutMs\", MAX_TIMER_DELAY_MS),\n maxFileCountDelta: parseIntegerAtLeast(block.maxFileCountDelta, 0, DEFAULT_MAX_FILE_COUNT_DELTA, \"replicaPeers.maxFileCountDelta\"),\n maxWatermarkAgeDeltaMs: parseIntegerAtLeast(\n block.maxWatermarkAgeDeltaMs,\n 0,\n DEFAULT_MAX_WATERMARK_AGE_DELTA_MS,\n \"replicaPeers.maxWatermarkAgeDeltaMs\",\n ),\n };\n}\n\n/**\n * READ-boundary resolver (mirrors `resolveExtractionLivenessConfig`, issue #2155).\n * `parseConfig` always populates `replicaPeers`, but a host adapter, an older\n * persisted config, or a hand-built `PluginConfig` can hand a READ surface\n * (/health, doctor) an absent, partial, or loosely-typed block. Every replica\n * surface must degrade to the documented default (disabled, no peers, no polling)\n * rather than throw — `/health` must stay answerable. Unlike the strict parser, a\n * present-but-invalid field falls back to its default here instead of throwing, and\n * a malformed peer entry is dropped rather than aborting the whole block.\n */\nexport function resolveReplicaPeersConfig(block: unknown): ReplicaPeersConfig {\n const record =\n block !== null && typeof block === \"object\" && !Array.isArray(block) ? (block as Record<string, unknown>) : {};\n return {\n enabled: coerceBool(record.enabled) ?? false,\n peers: resolveReplicaPeers(record.peers),\n pollIntervalMs: resolveIntegerAtLeast(record.pollIntervalMs, 1, DEFAULT_POLL_INTERVAL_MS),\n requestTimeoutMs: resolveIntegerAtLeast(record.requestTimeoutMs, 1, DEFAULT_REQUEST_TIMEOUT_MS, MAX_TIMER_DELAY_MS),\n maxFileCountDelta: resolveIntegerAtLeast(record.maxFileCountDelta, 0, DEFAULT_MAX_FILE_COUNT_DELTA),\n maxWatermarkAgeDeltaMs: resolveIntegerAtLeast(record.maxWatermarkAgeDeltaMs, 0, DEFAULT_MAX_WATERMARK_AGE_DELTA_MS),\n };\n}\n\n/** Lenient sibling of {@link parseIntegerAtLeast}: a present-but-invalid value falls back, never throws. */\nfunction resolveIntegerAtLeast(value: unknown, min: number, dflt: number, max = Number.MAX_SAFE_INTEGER): number {\n if (value === undefined) return dflt;\n const coerced = coerceNumber(value);\n return coerced !== undefined && Number.isFinite(coerced) && Number.isInteger(coerced) && coerced >= min && coerced <= max ? coerced : dflt;\n}\n\n/** Lenient peer list: a non-array is empty; a malformed entry is dropped, never thrown (read boundary). */\nfunction resolveReplicaPeers(value: unknown): ReplicaPeerConfig[] {\n if (!Array.isArray(value)) return [];\n const peers: ReplicaPeerConfig[] = [];\n value.forEach((entry, index) => {\n try {\n peers.push(parseReplicaPeer(entry, index));\n } catch {\n // Read surfaces never throw on a bad peer — parseConfig is the enforcing boundary.\n }\n });\n return peers;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,118 @@
1
+ import {
2
+ assertPathInsideRoot
3
+ } from "./chunk-GCASGYIO.js";
4
+ import {
5
+ getMemoryProjectionPath,
6
+ initializeMemoryProjectionDb
7
+ } from "./chunk-3CSX3ETE.js";
8
+ import {
9
+ openBetterSqlite3
10
+ } from "./chunk-RL6NEVXT.js";
11
+ import {
12
+ isErrnoCode
13
+ } from "./chunk-5UZXUTVO.js";
14
+
15
+ // src/memory-projection-mutations.ts
16
+ import { lstat, realpath } from "fs/promises";
17
+ var PROJECTION_WRITE_BUSY_TIMEOUT_MS = 100;
18
+ var PROJECTION_WRITE_RETRY_COUNT = 4;
19
+ var PROJECTION_WRITE_RETRY_DELAY_MS = 100;
20
+ function isSqliteBusyError(error) {
21
+ const messages = [];
22
+ const seen = /* @__PURE__ */ new Set();
23
+ let current = error;
24
+ while (current !== null && typeof current === "object" && !seen.has(current)) {
25
+ seen.add(current);
26
+ if (current instanceof Error) messages.push(current.message);
27
+ if (!("cause" in current)) break;
28
+ current = current.cause;
29
+ }
30
+ const lower = messages.join("\n").toLowerCase();
31
+ return lower.includes("database is locked") || lower.includes("sqlite_busy");
32
+ }
33
+ async function validateProjectionPath(memoryDir, projectionPath) {
34
+ let projectionStat;
35
+ try {
36
+ projectionStat = await lstat(projectionPath);
37
+ } catch (error) {
38
+ if (isErrnoCode(error, "ENOENT")) return false;
39
+ throw error;
40
+ }
41
+ if (projectionStat.isSymbolicLink() || !projectionStat.isFile()) {
42
+ throw new Error(`Refusing memory projection rewrite through unsafe database path: ${projectionPath}.`);
43
+ }
44
+ const [memoryRoot, projectionReal] = await Promise.all([
45
+ realpath(memoryDir),
46
+ realpath(projectionPath)
47
+ ]);
48
+ assertPathInsideRoot(memoryRoot, projectionReal, projectionPath);
49
+ return true;
50
+ }
51
+ async function rewriteProjectedEntityReferenceRows(memoryDir, entries, memoryId) {
52
+ if (memoryId !== void 0 && memoryId.length === 0) {
53
+ throw new Error("Projection memoryId must not be empty.");
54
+ }
55
+ const scopedMemory = memoryId !== void 0;
56
+ const validEntries = entries.filter(
57
+ ([previousEntityRef, nextEntityRef]) => previousEntityRef.length > 0 && nextEntityRef.length > 0 && previousEntityRef !== nextEntityRef
58
+ );
59
+ if (validEntries.length === 0) return;
60
+ const projectionPath = getMemoryProjectionPath(memoryDir);
61
+ if (!await validateProjectionPath(memoryDir, projectionPath)) return;
62
+ let lastError;
63
+ for (let attempt = 0; attempt < PROJECTION_WRITE_RETRY_COUNT; attempt += 1) {
64
+ if (!await validateProjectionPath(memoryDir, projectionPath)) return;
65
+ let db = null;
66
+ try {
67
+ db = openBetterSqlite3(projectionPath, { fileMustExist: true });
68
+ db.pragma(`busy_timeout = ${PROJECTION_WRITE_BUSY_TIMEOUT_MS}`);
69
+ initializeMemoryProjectionDb(db);
70
+ const updateCurrent = db.prepare(
71
+ scopedMemory ? "UPDATE memory_current SET entity_ref = ? WHERE memory_id = ? AND entity_ref = ?" : "UPDATE memory_current SET entity_ref = ? WHERE entity_ref = ?"
72
+ );
73
+ const updateMentions = db.prepare(
74
+ scopedMemory ? `
75
+ UPDATE memory_entity_mentions
76
+ SET entity_ref = ?
77
+ WHERE memory_id = ? AND entity_ref = ? AND mention_source = 'frontmatter.entityRef'
78
+ ` : `
79
+ UPDATE memory_entity_mentions
80
+ SET entity_ref = ?
81
+ WHERE entity_ref = ? AND mention_source = 'frontmatter.entityRef'
82
+ `
83
+ );
84
+ const rewrite = db.transaction(() => {
85
+ for (const [previousEntityRef, nextEntityRef] of validEntries) {
86
+ const params = scopedMemory ? [nextEntityRef, memoryId, previousEntityRef] : [nextEntityRef, previousEntityRef];
87
+ updateCurrent.run(...params);
88
+ updateMentions.run(...params);
89
+ }
90
+ });
91
+ rewrite();
92
+ return;
93
+ } catch (error) {
94
+ lastError = error;
95
+ if (!isSqliteBusyError(error) || attempt === PROJECTION_WRITE_RETRY_COUNT - 1) {
96
+ throw error;
97
+ }
98
+ const { promise, resolve } = Promise.withResolvers();
99
+ setTimeout(resolve, PROJECTION_WRITE_RETRY_DELAY_MS);
100
+ await promise;
101
+ } finally {
102
+ db?.close();
103
+ }
104
+ }
105
+ throw lastError instanceof Error ? lastError : new Error("Projection rewrite failed.");
106
+ }
107
+ async function rewriteProjectedMemoryEntityReference(memoryDir, memoryId, previousEntityRef, nextEntityRef) {
108
+ await rewriteProjectedEntityReferenceRows(memoryDir, [[previousEntityRef, nextEntityRef]], memoryId);
109
+ }
110
+ async function rewriteProjectedEntityReferences(memoryDir, replacements) {
111
+ await rewriteProjectedEntityReferenceRows(memoryDir, Object.entries(replacements));
112
+ }
113
+
114
+ export {
115
+ rewriteProjectedMemoryEntityReference,
116
+ rewriteProjectedEntityReferences
117
+ };
118
+ //# sourceMappingURL=chunk-WRJVB3C2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/memory-projection-mutations.ts"],"sourcesContent":["import { lstat, realpath } from \"node:fs/promises\";\nimport { isErrnoCode } from \"./utils/errno.js\";\nimport { assertPathInsideRoot } from \"./utils/path-containment.js\";\nimport { getMemoryProjectionPath, initializeMemoryProjectionDb } from \"./memory-projection-store.js\";\nimport { type BetterSqlite3Database, openBetterSqlite3 } from \"./runtime/better-sqlite.js\";\n\nconst PROJECTION_WRITE_BUSY_TIMEOUT_MS = 100;\nconst PROJECTION_WRITE_RETRY_COUNT = 4;\nconst PROJECTION_WRITE_RETRY_DELAY_MS = 100;\n\nfunction isSqliteBusyError(error: unknown): boolean {\n const messages: string[] = [];\n const seen = new Set<unknown>();\n let current: unknown = error;\n while (current !== null && typeof current === \"object\" && !seen.has(current)) {\n seen.add(current);\n if (current instanceof Error) messages.push(current.message);\n if (!(\"cause\" in current)) break;\n current = current.cause;\n }\n const lower = messages.join(\"\\n\").toLowerCase();\n return lower.includes(\"database is locked\") || lower.includes(\"sqlite_busy\");\n}\n\nasync function validateProjectionPath(\n memoryDir: string,\n projectionPath: string,\n): Promise<boolean> {\n let projectionStat;\n try {\n projectionStat = await lstat(projectionPath);\n } catch (error) {\n if (isErrnoCode(error, \"ENOENT\")) return false;\n throw error;\n }\n if (projectionStat.isSymbolicLink() || !projectionStat.isFile()) {\n throw new Error(`Refusing memory projection rewrite through unsafe database path: ${projectionPath}.`);\n }\n const [memoryRoot, projectionReal] = await Promise.all([\n realpath(memoryDir),\n realpath(projectionPath),\n ]);\n assertPathInsideRoot(memoryRoot, projectionReal, projectionPath);\n return true;\n}\n\nasync function rewriteProjectedEntityReferenceRows(\n memoryDir: string,\n entries: ReadonlyArray<readonly [string, string]>,\n memoryId?: string,\n): Promise<void> {\n if (memoryId !== undefined && memoryId.length === 0) {\n throw new Error(\"Projection memoryId must not be empty.\");\n }\n const scopedMemory = memoryId !== undefined;\n const validEntries = entries.filter(\n ([previousEntityRef, nextEntityRef]) =>\n previousEntityRef.length > 0 && nextEntityRef.length > 0 && previousEntityRef !== nextEntityRef,\n );\n if (validEntries.length === 0) return;\n\n const projectionPath = getMemoryProjectionPath(memoryDir);\n if (!(await validateProjectionPath(memoryDir, projectionPath))) return;\n\n let lastError: unknown;\n for (let attempt = 0; attempt < PROJECTION_WRITE_RETRY_COUNT; attempt += 1) {\n if (!(await validateProjectionPath(memoryDir, projectionPath))) return;\n let db: BetterSqlite3Database | null = null;\n try {\n db = openBetterSqlite3(projectionPath, { fileMustExist: true });\n db.pragma(`busy_timeout = ${PROJECTION_WRITE_BUSY_TIMEOUT_MS}`);\n initializeMemoryProjectionDb(db);\n const updateCurrent = db.prepare(\n scopedMemory\n ? \"UPDATE memory_current SET entity_ref = ? WHERE memory_id = ? AND entity_ref = ?\"\n : \"UPDATE memory_current SET entity_ref = ? WHERE entity_ref = ?\",\n );\n const updateMentions = db.prepare(\n scopedMemory\n ? `\n UPDATE memory_entity_mentions\n SET entity_ref = ?\n WHERE memory_id = ? AND entity_ref = ? AND mention_source = 'frontmatter.entityRef'\n `\n : `\n UPDATE memory_entity_mentions\n SET entity_ref = ?\n WHERE entity_ref = ? AND mention_source = 'frontmatter.entityRef'\n `,\n );\n const rewrite = db.transaction(() => {\n for (const [previousEntityRef, nextEntityRef] of validEntries) {\n const params = scopedMemory\n ? [nextEntityRef, memoryId, previousEntityRef]\n : [nextEntityRef, previousEntityRef];\n updateCurrent.run(...params);\n updateMentions.run(...params);\n }\n });\n rewrite();\n return;\n } catch (error) {\n lastError = error;\n if (!isSqliteBusyError(error) || attempt === PROJECTION_WRITE_RETRY_COUNT - 1) {\n throw error;\n }\n const { promise, resolve } = Promise.withResolvers<void>();\n setTimeout(resolve, PROJECTION_WRITE_RETRY_DELAY_MS);\n await promise;\n } finally {\n db?.close();\n }\n }\n\n throw lastError instanceof Error ? lastError : new Error(\"Projection rewrite failed.\");\n}\n\nexport async function rewriteProjectedMemoryEntityReference(\n memoryDir: string,\n memoryId: string,\n previousEntityRef: string,\n nextEntityRef: string,\n): Promise<void> {\n await rewriteProjectedEntityReferenceRows(memoryDir, [[previousEntityRef, nextEntityRef]], memoryId);\n}\n\nexport async function rewriteProjectedEntityReferences(\n memoryDir: string,\n replacements: Readonly<Record<string, string>>,\n): Promise<void> {\n await rewriteProjectedEntityReferenceRows(memoryDir, Object.entries(replacements));\n}\n"],"mappings":"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","names":[]}
@@ -4,17 +4,17 @@ import {
4
4
  import {
5
5
  loadPersistedNativeKnowledgeChunks
6
6
  } from "./chunk-2DQ2XREU.js";
7
- import {
8
- commitPreparedFileAtomically
9
- } from "./chunk-R6YJI3HE.js";
10
7
  import {
11
8
  listMemoryGovernanceRuns,
12
9
  readMemoryGovernanceRunArtifact
13
- } from "./chunk-FRVTCCGD.js";
10
+ } from "./chunk-GJPCP5CA.js";
11
+ import {
12
+ commitPreparedFileAtomically
13
+ } from "./chunk-R6YJI3HE.js";
14
14
  import {
15
15
  StorageManager,
16
16
  assertInjectedStorageRooted
17
- } from "./chunk-CIQXI47W.js";
17
+ } from "./chunk-Q5VJUNXA.js";
18
18
  import {
19
19
  MEMORY_LIFECYCLE_EVENT_SORT_ORDER,
20
20
  buildLifecycleEventsForMemory,
@@ -1024,4 +1024,4 @@ export {
1024
1024
  verifyMemoryProjection,
1025
1025
  repairMemoryProjection
1026
1026
  };
1027
- //# sourceMappingURL=chunk-BHLN7L7M.js.map
1027
+ //# sourceMappingURL=chunk-WVVK2RFM.js.map
@@ -246,4 +246,4 @@ export {
246
246
  decryptCapsuleFile,
247
247
  decryptCapsuleFileInMemory
248
248
  };
249
- //# sourceMappingURL=chunk-DQEMWVMT.js.map
249
+ //# sourceMappingURL=chunk-X7Y7WX73.js.map
@@ -1,9 +1,9 @@
1
- import {
2
- runGraphEdgeDecayMaintenanceAcrossNamespaces
3
- } from "./chunk-HNZKVLAN.js";
4
1
  import {
5
2
  normalizeDreamsStatusWindowHours
6
3
  } from "./chunk-EQWEIIKQ.js";
4
+ import {
5
+ runGraphEdgeDecayMaintenanceAcrossNamespaces
6
+ } from "./chunk-HNZKVLAN.js";
7
7
  import {
8
8
  runContradictionScan
9
9
  } from "./chunk-BJJAX3IZ.js";
@@ -28,13 +28,13 @@ import {
28
28
  defineOperation,
29
29
  parseNamespacePreflightWriteOp,
30
30
  resolveAuthorizedNamespaceWritablePreflight
31
- } from "./chunk-NUWMZIYZ.js";
31
+ } from "./chunk-UR5SIN7H.js";
32
32
  import {
33
33
  projectTagProjectId
34
34
  } from "./chunk-MQVINOJQ.js";
35
35
  import {
36
36
  validateBriefingFormat
37
- } from "./chunk-CI26JDZA.js";
37
+ } from "./chunk-GQSMYXKL.js";
38
38
  import {
39
39
  expandTildePath
40
40
  } from "./chunk-EYIEWJNI.js";
@@ -484,4 +484,4 @@ defineOperation({ name: "graph_events", description: "SSE graph events.", schema
484
484
  defineOperation({ name: "chat_message", description: "Chat message.", schema: strictSchema({ message: S.str, chatSessionId: S.str }), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
485
485
  defineOperation({ name: "chat_events", description: "SSE chat events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
486
486
  defineOperation({ name: "adapters_status", description: "Adapter registry metadata (issue #1850 round 5). Marker op: the HTTP transport builds the response from its own adapterRegistry, but the op still must be registered so it appears in listRegisteredOperations and enforceTokenOp can gate it for scoped tokens.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
487
- //# sourceMappingURL=chunk-HEXSNYJD.js.map
487
+ //# sourceMappingURL=chunk-YOBNCD3Z.js.map
@@ -0,0 +1,40 @@
1
+ // src/entity-id-normalization.ts
2
+ var BUILTIN_ALIASES = {
3
+ openclaw: "openclaw",
4
+ "open-claw": "openclaw"
5
+ };
6
+ function normalizeEntityNameWithPattern(raw, type, aliases, pattern, normalizeUnicode) {
7
+ const rawStr = typeof raw === "string" ? raw : "";
8
+ const typeStr = typeof type === "string" && type.trim().length > 0 ? type : "entity";
9
+ const typePrefix = `${typeStr.toLowerCase()}-`;
10
+ let name = normalizeUnicode ? rawStr.normalize("NFC").toLowerCase().trim() : rawStr.toLowerCase().trim();
11
+ if (name.startsWith(typePrefix)) name = name.slice(typePrefix.length);
12
+ let normalized = name.replace(pattern, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
13
+ let legacyNormalized;
14
+ if (normalizeUnicode) {
15
+ let legacyName = rawStr.toLowerCase().trim();
16
+ if (legacyName.startsWith(typePrefix)) legacyName = legacyName.slice(typePrefix.length);
17
+ legacyNormalized = legacyName.replace(/[^a-z0-9]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
18
+ }
19
+ const unicodeAlias = aliases !== void 0 && Object.hasOwn(aliases, normalized) ? aliases[normalized] : void 0;
20
+ const legacyAlias = legacyNormalized !== void 0 && legacyNormalized !== normalized && aliases !== void 0 && Object.hasOwn(aliases, legacyNormalized) ? aliases[legacyNormalized] : void 0;
21
+ const userAlias = typeof unicodeAlias === "string" && unicodeAlias.length > 0 ? unicodeAlias : legacyAlias;
22
+ if (typeof userAlias === "string" && userAlias.length > 0) {
23
+ normalized = userAlias;
24
+ } else if (Object.hasOwn(BUILTIN_ALIASES, normalized)) {
25
+ normalized = BUILTIN_ALIASES[normalized];
26
+ }
27
+ return `${typeStr.toLowerCase()}-${normalized}`;
28
+ }
29
+ function normalizeEntityName(raw, type, aliases) {
30
+ return normalizeEntityNameWithPattern(raw, type, aliases, /[^\p{L}\p{M}\p{N}]+/gu, true);
31
+ }
32
+ function normalizeLegacyEntityName(raw, type, aliases) {
33
+ return normalizeEntityNameWithPattern(raw, type, aliases, /[^a-z0-9]+/g, false);
34
+ }
35
+
36
+ export {
37
+ normalizeEntityName,
38
+ normalizeLegacyEntityName
39
+ };
40
+ //# sourceMappingURL=chunk-YXZG5TVN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entity-id-normalization.ts"],"sourcesContent":["const BUILTIN_ALIASES: Record<string, string> = {\n openclaw: \"openclaw\",\n \"open-claw\": \"openclaw\",\n};\n\nfunction normalizeEntityNameWithPattern(\n raw: string,\n type: string,\n aliases: Readonly<Record<string, string>> | undefined,\n pattern: RegExp,\n normalizeUnicode: boolean\n): string {\n const rawStr = typeof raw === \"string\" ? raw : \"\";\n const typeStr = typeof type === \"string\" && type.trim().length > 0 ? type : \"entity\";\n const typePrefix = `${typeStr.toLowerCase()}-`;\n let name = normalizeUnicode ? rawStr.normalize(\"NFC\").toLowerCase().trim() : rawStr.toLowerCase().trim();\n if (name.startsWith(typePrefix)) name = name.slice(typePrefix.length);\n\n let normalized = name.replace(pattern, \"-\").replace(/-+/g, \"-\").replace(/^-|-$/g, \"\");\n let legacyNormalized: string | undefined;\n if (normalizeUnicode) {\n let legacyName = rawStr.toLowerCase().trim();\n if (legacyName.startsWith(typePrefix)) legacyName = legacyName.slice(typePrefix.length);\n legacyNormalized = legacyName.replace(/[^a-z0-9]+/g, \"-\").replace(/-+/g, \"-\").replace(/^-|-$/g, \"\");\n }\n const unicodeAlias = aliases !== undefined && Object.hasOwn(aliases, normalized) ? aliases[normalized] : undefined;\n const legacyAlias =\n legacyNormalized !== undefined && legacyNormalized !== normalized && aliases !== undefined &&\n Object.hasOwn(aliases, legacyNormalized)\n ? aliases[legacyNormalized]\n : undefined;\n const userAlias =\n typeof unicodeAlias === \"string\" && unicodeAlias.length > 0\n ? unicodeAlias\n : legacyAlias;\n if (typeof userAlias === \"string\" && userAlias.length > 0) {\n normalized = userAlias;\n } else if (Object.hasOwn(BUILTIN_ALIASES, normalized)) {\n normalized = BUILTIN_ALIASES[normalized];\n }\n\n return `${typeStr.toLowerCase()}-${normalized}`;\n}\n\nexport function normalizeEntityName(raw: string, type: string, aliases?: Readonly<Record<string, string>>): string {\n return normalizeEntityNameWithPattern(raw, type, aliases, /[^\\p{L}\\p{M}\\p{N}]+/gu, true);\n}\n\nexport function normalizeLegacyEntityName(\n raw: string,\n type: string,\n aliases?: Readonly<Record<string, string>>\n): string {\n return normalizeEntityNameWithPattern(raw, type, aliases, /[^a-z0-9]+/g, false);\n}\n"],"mappings":";AAAA,IAAM,kBAA0C;AAAA,EAC9C,UAAU;AAAA,EACV,aAAa;AACf;AAEA,SAAS,+BACP,KACA,MACA,SACA,SACA,kBACQ;AACR,QAAM,SAAS,OAAO,QAAQ,WAAW,MAAM;AAC/C,QAAM,UAAU,OAAO,SAAS,YAAY,KAAK,KAAK,EAAE,SAAS,IAAI,OAAO;AAC5E,QAAM,aAAa,GAAG,QAAQ,YAAY,CAAC;AAC3C,MAAI,OAAO,mBAAmB,OAAO,UAAU,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,OAAO,YAAY,EAAE,KAAK;AACvG,MAAI,KAAK,WAAW,UAAU,EAAG,QAAO,KAAK,MAAM,WAAW,MAAM;AAEpE,MAAI,aAAa,KAAK,QAAQ,SAAS,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,UAAU,EAAE;AACpF,MAAI;AACJ,MAAI,kBAAkB;AACpB,QAAI,aAAa,OAAO,YAAY,EAAE,KAAK;AAC3C,QAAI,WAAW,WAAW,UAAU,EAAG,cAAa,WAAW,MAAM,WAAW,MAAM;AACtF,uBAAmB,WAAW,QAAQ,eAAe,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,UAAU,EAAE;AAAA,EACpG;AACA,QAAM,eAAe,YAAY,UAAa,OAAO,OAAO,SAAS,UAAU,IAAI,QAAQ,UAAU,IAAI;AACzG,QAAM,cACJ,qBAAqB,UAAa,qBAAqB,cAAc,YAAY,UACjF,OAAO,OAAO,SAAS,gBAAgB,IACnC,QAAQ,gBAAgB,IACxB;AACN,QAAM,YACJ,OAAO,iBAAiB,YAAY,aAAa,SAAS,IACtD,eACA;AACN,MAAI,OAAO,cAAc,YAAY,UAAU,SAAS,GAAG;AACzD,iBAAa;AAAA,EACf,WAAW,OAAO,OAAO,iBAAiB,UAAU,GAAG;AACrD,iBAAa,gBAAgB,UAAU;AAAA,EACzC;AAEA,SAAO,GAAG,QAAQ,YAAY,CAAC,IAAI,UAAU;AAC/C;AAEO,SAAS,oBAAoB,KAAa,MAAc,SAAoD;AACjH,SAAO,+BAA+B,KAAK,MAAM,SAAS,yBAAyB,IAAI;AACzF;AAEO,SAAS,0BACd,KACA,MACA,SACQ;AACR,SAAO,+BAA+B,KAAK,MAAM,SAAS,eAAe,KAAK;AAChF;","names":[]}