@fgv/ts-agent-memory 5.1.0-46 → 5.1.0-48

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 (336) hide show
  1. package/README.md +55 -0
  2. package/dist/packlets/ingest/orchestrator.js +115 -20
  3. package/dist/packlets/ingest/orchestrator.js.map +1 -1
  4. package/dist/packlets/observe/memoryObservationStore.js +6 -0
  5. package/dist/packlets/observe/memoryObservationStore.js.map +1 -1
  6. package/dist/packlets/observe/observer.js.map +1 -1
  7. package/dist/packlets/store/fileTreeMemoryStore.js +63 -135
  8. package/dist/packlets/store/fileTreeMemoryStore.js.map +1 -1
  9. package/dist/packlets/store/vectorMaintenance.js +251 -0
  10. package/dist/packlets/store/vectorMaintenance.js.map +1 -0
  11. package/dist/packlets/vector/inMemoryCosineIndex.js +81 -18
  12. package/dist/packlets/vector/inMemoryCosineIndex.js.map +1 -1
  13. package/dist/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
  14. package/dist/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
  15. package/dist/packlets/vector/vectorIndex.js.map +1 -1
  16. package/dist/ts-agent-memory.d.ts +389 -71
  17. package/lib/packlets/ingest/orchestrator.d.ts +62 -5
  18. package/lib/packlets/ingest/orchestrator.d.ts.map +1 -1
  19. package/lib/packlets/ingest/orchestrator.js +115 -20
  20. package/lib/packlets/ingest/orchestrator.js.map +1 -1
  21. package/lib/packlets/observe/memoryObservationStore.d.ts.map +1 -1
  22. package/lib/packlets/observe/memoryObservationStore.js +6 -0
  23. package/lib/packlets/observe/memoryObservationStore.js.map +1 -1
  24. package/lib/packlets/observe/observer.d.ts +61 -0
  25. package/lib/packlets/observe/observer.d.ts.map +1 -1
  26. package/lib/packlets/observe/observer.js.map +1 -1
  27. package/lib/packlets/store/fileTreeMemoryStore.d.ts +97 -60
  28. package/lib/packlets/store/fileTreeMemoryStore.d.ts.map +1 -1
  29. package/lib/packlets/store/fileTreeMemoryStore.js +63 -135
  30. package/lib/packlets/store/fileTreeMemoryStore.js.map +1 -1
  31. package/lib/packlets/store/vectorMaintenance.d.ts +149 -0
  32. package/lib/packlets/store/vectorMaintenance.d.ts.map +1 -0
  33. package/lib/packlets/store/vectorMaintenance.js +255 -0
  34. package/lib/packlets/store/vectorMaintenance.js.map +1 -0
  35. package/lib/packlets/vector/inMemoryCosineIndex.d.ts +30 -7
  36. package/lib/packlets/vector/inMemoryCosineIndex.d.ts.map +1 -1
  37. package/lib/packlets/vector/inMemoryCosineIndex.js +80 -17
  38. package/lib/packlets/vector/inMemoryCosineIndex.js.map +1 -1
  39. package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts +7 -0
  40. package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts.map +1 -1
  41. package/lib/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
  42. package/lib/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
  43. package/lib/packlets/vector/vectorIndex.d.ts +129 -1
  44. package/lib/packlets/vector/vectorIndex.d.ts.map +1 -1
  45. package/lib/packlets/vector/vectorIndex.js.map +1 -1
  46. package/package.json +17 -7
  47. package/.rush/temp/6e1299d1cebb080772163a532c221cd181b54f9f.tar.log +0 -462
  48. package/.rush/temp/chunked-rush-logs/ts-agent-memory.build.chunks.jsonl +0 -9
  49. package/.rush/temp/operation/build/all.log +0 -9
  50. package/.rush/temp/operation/build/log-chunks.jsonl +0 -9
  51. package/.rush/temp/operation/build/state.json +0 -3
  52. package/.rush/temp/shrinkwrap-deps.json +0 -689
  53. package/config/api-extractor.json +0 -343
  54. package/config/jest.config.json +0 -14
  55. package/config/rig.json +0 -4
  56. package/dist/test/unit/converters/antagonistRoundTrip.test.js +0 -95
  57. package/dist/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
  58. package/dist/test/unit/converters/bodyConverterRegistry.test.js +0 -72
  59. package/dist/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
  60. package/dist/test/unit/converters/envelopeConverter.test.js +0 -313
  61. package/dist/test/unit/converters/envelopeConverter.test.js.map +0 -1
  62. package/dist/test/unit/index/memoryIndex.test.js +0 -214
  63. package/dist/test/unit/index/memoryIndex.test.js.map +0 -1
  64. package/dist/test/unit/ingest/antagonistCycleAndParity.test.js +0 -277
  65. package/dist/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
  66. package/dist/test/unit/ingest/cycleGuard.test.js +0 -81
  67. package/dist/test/unit/ingest/cycleGuard.test.js.map +0 -1
  68. package/dist/test/unit/ingest/orchestrator.test.js +0 -1055
  69. package/dist/test/unit/ingest/orchestrator.test.js.map +0 -1
  70. package/dist/test/unit/observe/memoryObservationStore.test.js +0 -118
  71. package/dist/test/unit/observe/memoryObservationStore.test.js.map +0 -1
  72. package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -116
  73. package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
  74. package/dist/test/unit/retrieve/linkTraversalRetriever.test.js +0 -257
  75. package/dist/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
  76. package/dist/test/unit/retrieve/retrievers.test.js +0 -768
  77. package/dist/test/unit/retrieve/retrievers.test.js.map +0 -1
  78. package/dist/test/unit/retrieve/temporalRetrievers.test.js +0 -182
  79. package/dist/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
  80. package/dist/test/unit/store/antagonistTemporalBoundary.test.js +0 -120
  81. package/dist/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
  82. package/dist/test/unit/store/embedOnWrite.test.js +0 -317
  83. package/dist/test/unit/store/embedOnWrite.test.js.map +0 -1
  84. package/dist/test/unit/store/fileTreeMemoryStore.test.js +0 -778
  85. package/dist/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
  86. package/dist/test/unit/store/fragmentEmbedOnWrite.test.js +0 -255
  87. package/dist/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
  88. package/dist/test/unit/store/indexInjection.test.js +0 -432
  89. package/dist/test/unit/store/indexInjection.test.js.map +0 -1
  90. package/dist/test/unit/store/lenientOpen.test.js +0 -248
  91. package/dist/test/unit/store/lenientOpen.test.js.map +0 -1
  92. package/dist/test/unit/store/listScoped.test.js +0 -109
  93. package/dist/test/unit/store/listScoped.test.js.map +0 -1
  94. package/dist/test/unit/store/observations.test.js +0 -239
  95. package/dist/test/unit/store/observations.test.js.map +0 -1
  96. package/dist/test/unit/store/rankAxis.test.js +0 -254
  97. package/dist/test/unit/store/rankAxis.test.js.map +0 -1
  98. package/dist/test/unit/store/scopeEncoding.test.js +0 -24
  99. package/dist/test/unit/store/scopeEncoding.test.js.map +0 -1
  100. package/dist/test/unit/store/temporalStore.test.js +0 -398
  101. package/dist/test/unit/store/temporalStore.test.js.map +0 -1
  102. package/dist/test/unit/tools/memoryTools.test.js +0 -841
  103. package/dist/test/unit/tools/memoryTools.test.js.map +0 -1
  104. package/dist/test/unit/types/identityCodec.test.js +0 -187
  105. package/dist/test/unit/types/identityCodec.test.js.map +0 -1
  106. package/dist/test/unit/types/ids.test.js +0 -84
  107. package/dist/test/unit/types/ids.test.js.map +0 -1
  108. package/dist/test/unit/types/temporalCodec.test.js +0 -203
  109. package/dist/test/unit/types/temporalCodec.test.js.map +0 -1
  110. package/dist/test/unit/types/temporalPolicy.test.js +0 -83
  111. package/dist/test/unit/types/temporalPolicy.test.js.map +0 -1
  112. package/dist/test/unit/types/writePolicy.test.js +0 -331
  113. package/dist/test/unit/types/writePolicy.test.js.map +0 -1
  114. package/dist/test/unit/vector/fragmentConverters.test.js +0 -58
  115. package/dist/test/unit/vector/fragmentConverters.test.js.map +0 -1
  116. package/dist/test/unit/vector/inMemoryCosineIndex.test.js +0 -252
  117. package/dist/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
  118. package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -362
  119. package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
  120. package/dist/test/unit/vector/vectorIndex.test.js +0 -51
  121. package/dist/test/unit/vector/vectorIndex.test.js.map +0 -1
  122. package/eslint.config.js +0 -15
  123. package/etc/ts-agent-memory.api.md +0 -938
  124. package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts +0 -10
  125. package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts.map +0 -1
  126. package/lib/test/unit/converters/antagonistRoundTrip.test.js +0 -97
  127. package/lib/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
  128. package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts +0 -2
  129. package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts.map +0 -1
  130. package/lib/test/unit/converters/bodyConverterRegistry.test.js +0 -74
  131. package/lib/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
  132. package/lib/test/unit/converters/envelopeConverter.test.d.ts +0 -2
  133. package/lib/test/unit/converters/envelopeConverter.test.d.ts.map +0 -1
  134. package/lib/test/unit/converters/envelopeConverter.test.js +0 -315
  135. package/lib/test/unit/converters/envelopeConverter.test.js.map +0 -1
  136. package/lib/test/unit/index/memoryIndex.test.d.ts +0 -2
  137. package/lib/test/unit/index/memoryIndex.test.d.ts.map +0 -1
  138. package/lib/test/unit/index/memoryIndex.test.js +0 -216
  139. package/lib/test/unit/index/memoryIndex.test.js.map +0 -1
  140. package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts +0 -9
  141. package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts.map +0 -1
  142. package/lib/test/unit/ingest/antagonistCycleAndParity.test.js +0 -279
  143. package/lib/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
  144. package/lib/test/unit/ingest/cycleGuard.test.d.ts +0 -2
  145. package/lib/test/unit/ingest/cycleGuard.test.d.ts.map +0 -1
  146. package/lib/test/unit/ingest/cycleGuard.test.js +0 -83
  147. package/lib/test/unit/ingest/cycleGuard.test.js.map +0 -1
  148. package/lib/test/unit/ingest/orchestrator.test.d.ts +0 -2
  149. package/lib/test/unit/ingest/orchestrator.test.d.ts.map +0 -1
  150. package/lib/test/unit/ingest/orchestrator.test.js +0 -1057
  151. package/lib/test/unit/ingest/orchestrator.test.js.map +0 -1
  152. package/lib/test/unit/observe/memoryObservationStore.test.d.ts +0 -2
  153. package/lib/test/unit/observe/memoryObservationStore.test.d.ts.map +0 -1
  154. package/lib/test/unit/observe/memoryObservationStore.test.js +0 -120
  155. package/lib/test/unit/observe/memoryObservationStore.test.js.map +0 -1
  156. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts +0 -2
  157. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts.map +0 -1
  158. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -118
  159. package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
  160. package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts +0 -2
  161. package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts.map +0 -1
  162. package/lib/test/unit/retrieve/linkTraversalRetriever.test.js +0 -259
  163. package/lib/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
  164. package/lib/test/unit/retrieve/retrievers.test.d.ts +0 -2
  165. package/lib/test/unit/retrieve/retrievers.test.d.ts.map +0 -1
  166. package/lib/test/unit/retrieve/retrievers.test.js +0 -770
  167. package/lib/test/unit/retrieve/retrievers.test.js.map +0 -1
  168. package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts +0 -2
  169. package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts.map +0 -1
  170. package/lib/test/unit/retrieve/temporalRetrievers.test.js +0 -184
  171. package/lib/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
  172. package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts +0 -9
  173. package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts.map +0 -1
  174. package/lib/test/unit/store/antagonistTemporalBoundary.test.js +0 -122
  175. package/lib/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
  176. package/lib/test/unit/store/embedOnWrite.test.d.ts +0 -2
  177. package/lib/test/unit/store/embedOnWrite.test.d.ts.map +0 -1
  178. package/lib/test/unit/store/embedOnWrite.test.js +0 -319
  179. package/lib/test/unit/store/embedOnWrite.test.js.map +0 -1
  180. package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts +0 -2
  181. package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts.map +0 -1
  182. package/lib/test/unit/store/fileTreeMemoryStore.test.js +0 -780
  183. package/lib/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
  184. package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts +0 -2
  185. package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts.map +0 -1
  186. package/lib/test/unit/store/fragmentEmbedOnWrite.test.js +0 -257
  187. package/lib/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
  188. package/lib/test/unit/store/indexInjection.test.d.ts +0 -2
  189. package/lib/test/unit/store/indexInjection.test.d.ts.map +0 -1
  190. package/lib/test/unit/store/indexInjection.test.js +0 -434
  191. package/lib/test/unit/store/indexInjection.test.js.map +0 -1
  192. package/lib/test/unit/store/lenientOpen.test.d.ts +0 -2
  193. package/lib/test/unit/store/lenientOpen.test.d.ts.map +0 -1
  194. package/lib/test/unit/store/lenientOpen.test.js +0 -250
  195. package/lib/test/unit/store/lenientOpen.test.js.map +0 -1
  196. package/lib/test/unit/store/listScoped.test.d.ts +0 -2
  197. package/lib/test/unit/store/listScoped.test.d.ts.map +0 -1
  198. package/lib/test/unit/store/listScoped.test.js +0 -111
  199. package/lib/test/unit/store/listScoped.test.js.map +0 -1
  200. package/lib/test/unit/store/observations.test.d.ts +0 -2
  201. package/lib/test/unit/store/observations.test.d.ts.map +0 -1
  202. package/lib/test/unit/store/observations.test.js +0 -241
  203. package/lib/test/unit/store/observations.test.js.map +0 -1
  204. package/lib/test/unit/store/rankAxis.test.d.ts +0 -2
  205. package/lib/test/unit/store/rankAxis.test.d.ts.map +0 -1
  206. package/lib/test/unit/store/rankAxis.test.js +0 -256
  207. package/lib/test/unit/store/rankAxis.test.js.map +0 -1
  208. package/lib/test/unit/store/scopeEncoding.test.d.ts +0 -2
  209. package/lib/test/unit/store/scopeEncoding.test.d.ts.map +0 -1
  210. package/lib/test/unit/store/scopeEncoding.test.js +0 -26
  211. package/lib/test/unit/store/scopeEncoding.test.js.map +0 -1
  212. package/lib/test/unit/store/temporalStore.test.d.ts +0 -2
  213. package/lib/test/unit/store/temporalStore.test.d.ts.map +0 -1
  214. package/lib/test/unit/store/temporalStore.test.js +0 -400
  215. package/lib/test/unit/store/temporalStore.test.js.map +0 -1
  216. package/lib/test/unit/tools/memoryTools.test.d.ts +0 -2
  217. package/lib/test/unit/tools/memoryTools.test.d.ts.map +0 -1
  218. package/lib/test/unit/tools/memoryTools.test.js +0 -843
  219. package/lib/test/unit/tools/memoryTools.test.js.map +0 -1
  220. package/lib/test/unit/types/identityCodec.test.d.ts +0 -2
  221. package/lib/test/unit/types/identityCodec.test.d.ts.map +0 -1
  222. package/lib/test/unit/types/identityCodec.test.js +0 -189
  223. package/lib/test/unit/types/identityCodec.test.js.map +0 -1
  224. package/lib/test/unit/types/ids.test.d.ts +0 -2
  225. package/lib/test/unit/types/ids.test.d.ts.map +0 -1
  226. package/lib/test/unit/types/ids.test.js +0 -86
  227. package/lib/test/unit/types/ids.test.js.map +0 -1
  228. package/lib/test/unit/types/temporalCodec.test.d.ts +0 -2
  229. package/lib/test/unit/types/temporalCodec.test.d.ts.map +0 -1
  230. package/lib/test/unit/types/temporalCodec.test.js +0 -205
  231. package/lib/test/unit/types/temporalCodec.test.js.map +0 -1
  232. package/lib/test/unit/types/temporalPolicy.test.d.ts +0 -2
  233. package/lib/test/unit/types/temporalPolicy.test.d.ts.map +0 -1
  234. package/lib/test/unit/types/temporalPolicy.test.js +0 -85
  235. package/lib/test/unit/types/temporalPolicy.test.js.map +0 -1
  236. package/lib/test/unit/types/writePolicy.test.d.ts +0 -2
  237. package/lib/test/unit/types/writePolicy.test.d.ts.map +0 -1
  238. package/lib/test/unit/types/writePolicy.test.js +0 -333
  239. package/lib/test/unit/types/writePolicy.test.js.map +0 -1
  240. package/lib/test/unit/vector/fragmentConverters.test.d.ts +0 -2
  241. package/lib/test/unit/vector/fragmentConverters.test.d.ts.map +0 -1
  242. package/lib/test/unit/vector/fragmentConverters.test.js +0 -60
  243. package/lib/test/unit/vector/fragmentConverters.test.js.map +0 -1
  244. package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts +0 -2
  245. package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts.map +0 -1
  246. package/lib/test/unit/vector/inMemoryCosineIndex.test.js +0 -254
  247. package/lib/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
  248. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts +0 -2
  249. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts.map +0 -1
  250. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -364
  251. package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
  252. package/lib/test/unit/vector/vectorIndex.test.d.ts +0 -2
  253. package/lib/test/unit/vector/vectorIndex.test.d.ts.map +0 -1
  254. package/lib/test/unit/vector/vectorIndex.test.js +0 -53
  255. package/lib/test/unit/vector/vectorIndex.test.js.map +0 -1
  256. package/rush-logs/ts-agent-memory.build.cache.log +0 -3
  257. package/rush-logs/ts-agent-memory.build.log +0 -9
  258. package/src/index.ts +0 -14
  259. package/src/packlets/converters/bodyConverterRegistry.ts +0 -105
  260. package/src/packlets/converters/envelopeConverter.ts +0 -233
  261. package/src/packlets/converters/index.ts +0 -7
  262. package/src/packlets/index/index.ts +0 -6
  263. package/src/packlets/index/memoryIndex.ts +0 -332
  264. package/src/packlets/ingest/cycleGuard.ts +0 -153
  265. package/src/packlets/ingest/hostStages.ts +0 -111
  266. package/src/packlets/ingest/index.ts +0 -9
  267. package/src/packlets/ingest/model.ts +0 -195
  268. package/src/packlets/ingest/orchestrator.ts +0 -873
  269. package/src/packlets/observe/index.ts +0 -7
  270. package/src/packlets/observe/memoryObservationStore.ts +0 -153
  271. package/src/packlets/observe/observer.ts +0 -119
  272. package/src/packlets/retrieve/fragmentSemanticRetriever.ts +0 -138
  273. package/src/packlets/retrieve/hybridRetriever.ts +0 -194
  274. package/src/packlets/retrieve/index.ts +0 -14
  275. package/src/packlets/retrieve/linkTraversalRetriever.ts +0 -158
  276. package/src/packlets/retrieve/recencyRetriever.ts +0 -54
  277. package/src/packlets/retrieve/retriever.ts +0 -291
  278. package/src/packlets/retrieve/semanticRetriever.ts +0 -152
  279. package/src/packlets/retrieve/structuredFilterRetriever.ts +0 -58
  280. package/src/packlets/retrieve/tagRetriever.ts +0 -58
  281. package/src/packlets/retrieve/temporalRetrievers.ts +0 -210
  282. package/src/packlets/store/fileTreeMemoryStore.ts +0 -1834
  283. package/src/packlets/store/index.ts +0 -7
  284. package/src/packlets/store/scopeEncoding.ts +0 -36
  285. package/src/packlets/tools/index.ts +0 -6
  286. package/src/packlets/tools/memoryTools.ts +0 -706
  287. package/src/packlets/types/envelope.ts +0 -196
  288. package/src/packlets/types/filenameSafety.ts +0 -57
  289. package/src/packlets/types/identityCodec.ts +0 -447
  290. package/src/packlets/types/ids.ts +0 -124
  291. package/src/packlets/types/index.ts +0 -11
  292. package/src/packlets/types/temporal.ts +0 -96
  293. package/src/packlets/types/writePolicy.ts +0 -612
  294. package/src/packlets/vector/fragmentConverters.ts +0 -55
  295. package/src/packlets/vector/inMemoryCosineIndex.ts +0 -196
  296. package/src/packlets/vector/inMemoryFragmentCosineIndex.ts +0 -289
  297. package/src/packlets/vector/index.ts +0 -9
  298. package/src/packlets/vector/vectorIndex.ts +0 -273
  299. package/src/test/unit/converters/antagonistRoundTrip.test.ts +0 -110
  300. package/src/test/unit/converters/bodyConverterRegistry.test.ts +0 -89
  301. package/src/test/unit/converters/envelopeConverter.test.ts +0 -418
  302. package/src/test/unit/index/memoryIndex.test.ts +0 -272
  303. package/src/test/unit/ingest/antagonistCycleAndParity.test.ts +0 -367
  304. package/src/test/unit/ingest/cycleGuard.test.ts +0 -110
  305. package/src/test/unit/ingest/orchestrator.test.ts +0 -1351
  306. package/src/test/unit/observe/memoryObservationStore.test.ts +0 -158
  307. package/src/test/unit/retrieve/fragmentSemanticRetriever.test.ts +0 -163
  308. package/src/test/unit/retrieve/linkTraversalRetriever.test.ts +0 -329
  309. package/src/test/unit/retrieve/retrievers.test.ts +0 -1018
  310. package/src/test/unit/retrieve/temporalRetrievers.test.ts +0 -226
  311. package/src/test/unit/store/antagonistTemporalBoundary.test.ts +0 -158
  312. package/src/test/unit/store/embedOnWrite.test.ts +0 -418
  313. package/src/test/unit/store/fileTreeMemoryStore.test.ts +0 -1041
  314. package/src/test/unit/store/fragmentEmbedOnWrite.test.ts +0 -349
  315. package/src/test/unit/store/indexInjection.test.ts +0 -550
  316. package/src/test/unit/store/lenientOpen.test.ts +0 -292
  317. package/src/test/unit/store/listScoped.test.ts +0 -138
  318. package/src/test/unit/store/observations.test.ts +0 -290
  319. package/src/test/unit/store/rankAxis.test.ts +0 -349
  320. package/src/test/unit/store/scopeEncoding.test.ts +0 -37
  321. package/src/test/unit/store/temporalStore.test.ts +0 -469
  322. package/src/test/unit/tools/memoryTools.test.ts +0 -1120
  323. package/src/test/unit/types/identityCodec.test.ts +0 -266
  324. package/src/test/unit/types/ids.test.ts +0 -94
  325. package/src/test/unit/types/temporalCodec.test.ts +0 -259
  326. package/src/test/unit/types/temporalPolicy.test.ts +0 -124
  327. package/src/test/unit/types/writePolicy.test.ts +0 -446
  328. package/src/test/unit/vector/fragmentConverters.test.ts +0 -80
  329. package/src/test/unit/vector/inMemoryCosineIndex.test.ts +0 -318
  330. package/src/test/unit/vector/inMemoryFragmentCosineIndex.test.ts +0 -477
  331. package/src/test/unit/vector/vectorIndex.test.ts +0 -64
  332. package/temp/build/lint/_eslint-5eVG3S6w.json +0 -302
  333. package/temp/build/typescript/ts_8nwakTlr.json +0 -1
  334. package/temp/ts-agent-memory.api.json +0 -20933
  335. package/temp/ts-agent-memory.api.md +0 -938
  336. package/tsconfig.json +0 -8
@@ -150,7 +150,9 @@ export declare class MemoryIngestOrchestrator implements IMemoryIngestOrchestrat
150
150
  private _planFromVerdict;
151
151
  /**
152
152
  * Stage 4 — resolve a dedup verdict. Layer 1: an exact `{ kind, body }` match in
153
- * the candidate's scope is a `duplicate-of` (design note §1). Layer 2 (only when
153
+ * the candidate's scope is a `duplicate-of`, at the granularity the kind's
154
+ * {@link DedupScope} declares — scope-wide for `'content'`, restricted to the
155
+ * candidate's own entity for `'entity'` (design note §1). Layer 2 (only when
154
156
  * a resolver + vector index + embedder are all wired): embed the candidate,
155
157
  * surface over-threshold neighbors, and dispatch to the {@link IEntityResolver}.
156
158
  * Otherwise the verdict is `new` (the exact-only fall-back path).
@@ -161,9 +163,26 @@ export declare class MemoryIngestOrchestrator implements IMemoryIngestOrchestrat
161
163
  /** Layer-2 continuation once the candidate has a provisional record to embed. */
162
164
  private _resolveViaSimilarityEmbedded;
163
165
  /**
164
- * Find an existing record in `scope` whose `{ kind, body }` hash matches the
165
- * candidate's (layer-1 exact dedup). Invalidated temporal versions are excluded
166
- * — only a live (non-temporal or current) record deduplicates a candidate.
166
+ * Find an existing record whose `{ kind, body }` hash matches the candidate's
167
+ * (layer-1 exact dedup, design note §1). Invalidated temporal versions are
168
+ * excluded — only a live (non-temporal or current) record deduplicates a
169
+ * candidate.
170
+ *
171
+ * @remarks
172
+ * The cohort's granularity is the kind's DECLARED {@link DedupScope}, read
173
+ * through {@link IMemoryStore.dedupScopeFor} so this layer and the store's own
174
+ * write path can never disagree:
175
+ *
176
+ * - `'content'` — every live same-kind record in the candidate's scope,
177
+ * regardless of entity. A cross-id body collision IS a duplicate (the
178
+ * knowledge family; unchanged behavior).
179
+ * - `'entity'` — only records at the candidate's OWN entity address. Two
180
+ * distinct entities with byte-identical bodies never collapse into one
181
+ * another, which is what the declaration has always meant on the direct-put
182
+ * path and now means here too.
183
+ *
184
+ * The same-id collapse itself remains the store's job — this layer only decides
185
+ * whether a cross-id body collision is eligible to be a `duplicate-of` at all.
167
186
  */
168
187
  private _findExactMatch;
169
188
  /**
@@ -175,8 +194,46 @@ export declare class MemoryIngestOrchestrator implements IMemoryIngestOrchestrat
175
194
  private static _recordBodyString;
176
195
  /** The stage-4 exact-dedup key over `{ kind, body }` (design note §1). */
177
196
  private _exactKey;
178
- /** Stage 5 — relate (host), validate edges, and run the write-time cycle guard. */
197
+ /** Stage 5 — relate (host), redirect collapsed targets, validate edges, and run the write-time cycle guard. */
179
198
  private _relate;
199
+ /**
200
+ * The stage-5 edge-target redirect map for this pass: every `duplicate-of`
201
+ * candidate's OWN scoped address, mapped to the address of the record its
202
+ * verdict collapsed it into (design note §3).
203
+ *
204
+ * @remarks
205
+ * A `duplicate-of` verdict means "this candidate IS that record". The candidate
206
+ * is therefore not written, and its address never becomes a live reference — so
207
+ * a sibling edge built against it in the same pass would resolve to neither a
208
+ * written candidate nor an existing record and would fail the WHOLE ingest item.
209
+ * That is a second-order hazard of collapsing, not a defect in the edge: the
210
+ * host related two candidates it was correctly told about, and one of them
211
+ * turned out to already exist.
212
+ *
213
+ * Redirecting is the honest repair, and it is independent of {@link DedupScope}
214
+ * — it applies equally to a `'content'` kind, where the collapse is exactly
215
+ * right and the ingest still must not fail.
216
+ *
217
+ * The map cannot chain: {@link MemoryIngestOrchestrator._planFromVerdict}
218
+ * requires every target-bearing verdict's target to already exist in the store
219
+ * snapshot, so a redirect destination is always a persisted record and never
220
+ * another collapsed candidate. One pass is sufficient by construction.
221
+ */
222
+ private static _collapseRedirects;
223
+ /**
224
+ * Rewrite each edge whose TARGET names a collapsed candidate to point at the
225
+ * record that candidate collapsed into.
226
+ *
227
+ * @remarks
228
+ * Only the target is redirected. An edge whose SOURCE is a collapsed candidate
229
+ * stays untouched and is still rejected by {@link
230
+ * MemoryIngestOrchestrator._validateEdges}: sources are the records an edge is
231
+ * written ONTO, a collapsed candidate is never written, and the relation
232
+ * extractor is only ever offered writable candidates as edge sources in the
233
+ * first place. Silently relocating such an edge onto an existing record would
234
+ * attribute a link the host never asked for — the loud failure is correct there.
235
+ */
236
+ private static _redirectEdges;
180
237
  /**
181
238
  * Validate stage-5 edges: each `source` must be a candidate being written; each
182
239
  * `target` must resolve to a sibling candidate or an existing store record. All
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/packlets/ingest/orchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/packlets/ingest/orchestrator.ts"],"names":[],"mappings":"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"}
@@ -118,7 +118,7 @@ class MemoryIngestOrchestrator {
118
118
  }
119
119
  // Stage 5: relate over the writable candidates, validate + cycle-guard.
120
120
  const writablePlans = plans.filter((plan) => plan.verdict.verdict !== 'duplicate-of');
121
- const edgesResult = await this._relate(item, writablePlans, scoped, byKey);
121
+ const edgesResult = await this._relate(item, writablePlans, MemoryIngestOrchestrator._collapseRedirects(plans), scoped, byKey);
122
122
  if (edgesResult.isFailure()) {
123
123
  return (0, ts_utils_1.fail)(edgesResult.message);
124
124
  }
@@ -214,13 +214,15 @@ class MemoryIngestOrchestrator {
214
214
  }
215
215
  /**
216
216
  * Stage 4 — resolve a dedup verdict. Layer 1: an exact `{ kind, body }` match in
217
- * the candidate's scope is a `duplicate-of` (design note §1). Layer 2 (only when
217
+ * the candidate's scope is a `duplicate-of`, at the granularity the kind's
218
+ * {@link DedupScope} declares — scope-wide for `'content'`, restricted to the
219
+ * candidate's own entity for `'entity'` (design note §1). Layer 2 (only when
218
220
  * a resolver + vector index + embedder are all wired): embed the candidate,
219
221
  * surface over-threshold neighbors, and dispatch to the {@link IEntityResolver}.
220
222
  * Otherwise the verdict is `new` (the exact-only fall-back path).
221
223
  */
222
224
  async _resolveVerdict(candidate, kind, body, addr, snapshot, byKey) {
223
- return this._findExactMatch(kind, body, addr.scope, snapshot).thenOnSuccess(async (matchId) => {
225
+ return this._findExactMatch(kind, body, addr, snapshot).thenOnSuccess(async (matchId) => {
224
226
  if (matchId !== undefined) {
225
227
  // The exact-match cohort is filtered to `addr.scope`, so the match lives
226
228
  // under that scope — its scope-qualified target is `(addr.scope, matchId)`.
@@ -244,7 +246,17 @@ class MemoryIngestOrchestrator {
244
246
  if (embedded.isFailure()) {
245
247
  return (0, ts_utils_1.fail)(embedded.message);
246
248
  }
247
- const queried = await this._capture(() => wiring.vectorIndex.query(embedded.value, this._similarityTopK), `ingest '${candidate.envelope.entityId}': similarity query`);
249
+ // The embedder deliberately declined this candidate, so there is no vector to
250
+ // search with and layer-2 similarity dedup cannot run for it. That is the same
251
+ // position as a search that found nothing similar — `'new'` — and not an
252
+ // error: declining to embed a kind must not make it un-ingestable.
253
+ if (embedded.value === undefined) {
254
+ return (0, ts_utils_1.succeed)({ verdict: 'new' });
255
+ }
256
+ // Hoisted: the `undefined` check above does not narrow across the callback
257
+ // boundary below, and a local keeps the non-null assertion out of the code.
258
+ const vector = embedded.value;
259
+ const queried = await this._capture(() => wiring.vectorIndex.query(vector, this._similarityTopK), `ingest '${candidate.envelope.entityId}': similarity query`);
248
260
  if (queried.isFailure()) {
249
261
  return (0, ts_utils_1.fail)(queried.message);
250
262
  }
@@ -272,19 +284,44 @@ class MemoryIngestOrchestrator {
272
284
  return this._capture(() => wiring.resolver.resolve(candidate, similar), `ingest '${candidate.envelope.entityId}': resolve`);
273
285
  }
274
286
  /**
275
- * Find an existing record in `scope` whose `{ kind, body }` hash matches the
276
- * candidate's (layer-1 exact dedup). Invalidated temporal versions are excluded
277
- * — only a live (non-temporal or current) record deduplicates a candidate.
287
+ * Find an existing record whose `{ kind, body }` hash matches the candidate's
288
+ * (layer-1 exact dedup, design note §1). Invalidated temporal versions are
289
+ * excluded — only a live (non-temporal or current) record deduplicates a
290
+ * candidate.
291
+ *
292
+ * @remarks
293
+ * The cohort's granularity is the kind's DECLARED {@link DedupScope}, read
294
+ * through {@link IMemoryStore.dedupScopeFor} so this layer and the store's own
295
+ * write path can never disagree:
296
+ *
297
+ * - `'content'` — every live same-kind record in the candidate's scope,
298
+ * regardless of entity. A cross-id body collision IS a duplicate (the
299
+ * knowledge family; unchanged behavior).
300
+ * - `'entity'` — only records at the candidate's OWN entity address. Two
301
+ * distinct entities with byte-identical bodies never collapse into one
302
+ * another, which is what the declaration has always meant on the direct-put
303
+ * path and now means here too.
304
+ *
305
+ * The same-id collapse itself remains the store's job — this layer only decides
306
+ * whether a cross-id body collision is eligible to be a `duplicate-of` at all.
278
307
  */
279
- _findExactMatch(kind, body, scope, snapshot) {
308
+ _findExactMatch(kind, body, addr, snapshot) {
309
+ const dedupScope = this._store.dedupScopeFor(kind);
280
310
  // Same-kind, same-scope, LIVE (non-temporal or current) records are the exact
281
- // cohort. `_resolveAddress(...).map(...).orDefault()` collapses an unresolved
282
- // codec to a non-matching scope with no explicit failure branch.
283
- const cohort = snapshot.filter((record) => record.envelope.kind === kind &&
284
- !((0, types_1.isTemporalRecord)(record) && !(0, types_1.isVersionCurrent)(record)) &&
285
- this._resolveAddress(record.envelope.entityId, record.envelope.kind)
286
- .onSuccess((addr) => (0, ts_utils_1.succeed)(addr.scope))
287
- .orDefault() === scope);
311
+ // cohort, narrowed to the candidate's own entity address under `'entity'`
312
+ // granularity. `_resolveAddress(...).orDefault()` collapses an unresolved
313
+ // codec to `undefined` a non-matching address — with no explicit failure
314
+ // branch, exactly as the scope-only filter did before.
315
+ const cohort = snapshot.filter((record) => {
316
+ if (record.envelope.kind !== kind || ((0, types_1.isTemporalRecord)(record) && !(0, types_1.isVersionCurrent)(record))) {
317
+ return false;
318
+ }
319
+ const recordAddr = this._resolveAddress(record.envelope.entityId, record.envelope.kind).orDefault();
320
+ if (recordAddr === undefined || recordAddr.scope !== addr.scope) {
321
+ return false;
322
+ }
323
+ return dedupScope === 'content' || recordAddr.idStem === addr.idStem;
324
+ });
288
325
  return this._exactKey(kind, body).onSuccess((key) => (0, ts_utils_1.mapResults)(cohort.map((record) => MemoryIngestOrchestrator._recordBodyString(record).onSuccess((recordBody) => this._exactKey(record.envelope.kind, recordBody).onSuccess((recordKey) => (0, ts_utils_1.succeed)({ id: record.envelope.id, key: recordKey }))))).onSuccess((keyed) => { var _a; return (0, ts_utils_1.succeed)((_a = keyed.find((entry) => entry.key === key)) === null || _a === void 0 ? void 0 : _a.id); }));
289
326
  }
290
327
  /**
@@ -303,8 +340,8 @@ class MemoryIngestOrchestrator {
303
340
  _exactKey(kind, body) {
304
341
  return this._hasher.computeHash({ kind, body });
305
342
  }
306
- /** Stage 5 — relate (host), validate edges, and run the write-time cycle guard. */
307
- async _relate(item, writablePlans, scoped, byKey) {
343
+ /** Stage 5 — relate (host), redirect collapsed targets, validate edges, and run the write-time cycle guard. */
344
+ async _relate(item, writablePlans, redirects, scoped, byKey) {
308
345
  const relationCandidates = writablePlans.map((plan) => ({
309
346
  candidate: plan.candidate,
310
347
  id: plan.refTarget
@@ -313,21 +350,79 @@ class MemoryIngestOrchestrator {
313
350
  if (proposed.isFailure()) {
314
351
  return proposed;
315
352
  }
353
+ // Redirect BEFORE validation and BEFORE the cycle guard: an edge naming a
354
+ // collapsed candidate must be judged — and persisted — against the record it
355
+ // collapsed into, not against the address that no longer gets written.
356
+ const edges = MemoryIngestOrchestrator._redirectEdges(proposed.value, redirects);
316
357
  // refIds and the existing-record view (`byKey`, shared with the verdict path)
317
358
  // both key on the canonical scoped address, so a stem reused across scopes
318
359
  // never aliases.
319
360
  const refIds = new Set(writablePlans.map((plan) => (0, types_1.edgeTargetKey)(plan.refTarget)));
320
- const validation = this._validateEdges(item, proposed.value, refIds, byKey);
361
+ const validation = this._validateEdges(item, edges, refIds, byKey);
321
362
  if (validation.isFailure()) {
322
363
  return (0, ts_utils_1.fail)(validation.message);
323
364
  }
324
365
  if (this._cycleGuard === 'reject') {
325
- const guard = (0, cycleGuard_1.assertNoCycles)(MemoryIngestOrchestrator._existingEdges(scoped), proposed.value.map((e) => ({ source: e.source, target: e.edge.target, type: e.edge.type })));
366
+ const guard = (0, cycleGuard_1.assertNoCycles)(MemoryIngestOrchestrator._existingEdges(scoped), edges.map((e) => ({ source: e.source, target: e.edge.target, type: e.edge.type })));
326
367
  if (guard.isFailure()) {
327
368
  return (0, ts_utils_1.fail)(`ingest '${item.id}': ${guard.message}`);
328
369
  }
329
370
  }
330
- return (0, ts_utils_1.succeed)(proposed.value);
371
+ return (0, ts_utils_1.succeed)(edges);
372
+ }
373
+ /**
374
+ * The stage-5 edge-target redirect map for this pass: every `duplicate-of`
375
+ * candidate's OWN scoped address, mapped to the address of the record its
376
+ * verdict collapsed it into (design note §3).
377
+ *
378
+ * @remarks
379
+ * A `duplicate-of` verdict means "this candidate IS that record". The candidate
380
+ * is therefore not written, and its address never becomes a live reference — so
381
+ * a sibling edge built against it in the same pass would resolve to neither a
382
+ * written candidate nor an existing record and would fail the WHOLE ingest item.
383
+ * That is a second-order hazard of collapsing, not a defect in the edge: the
384
+ * host related two candidates it was correctly told about, and one of them
385
+ * turned out to already exist.
386
+ *
387
+ * Redirecting is the honest repair, and it is independent of {@link DedupScope}
388
+ * — it applies equally to a `'content'` kind, where the collapse is exactly
389
+ * right and the ingest still must not fail.
390
+ *
391
+ * The map cannot chain: {@link MemoryIngestOrchestrator._planFromVerdict}
392
+ * requires every target-bearing verdict's target to already exist in the store
393
+ * snapshot, so a redirect destination is always a persisted record and never
394
+ * another collapsed candidate. One pass is sufficient by construction.
395
+ */
396
+ static _collapseRedirects(plans) {
397
+ const redirects = new Map();
398
+ for (const plan of plans) {
399
+ if (plan.verdict.verdict === 'duplicate-of') {
400
+ redirects.set((0, types_1.edgeTargetKey)(plan.refTarget), plan.verdict.target);
401
+ }
402
+ }
403
+ return redirects;
404
+ }
405
+ /**
406
+ * Rewrite each edge whose TARGET names a collapsed candidate to point at the
407
+ * record that candidate collapsed into.
408
+ *
409
+ * @remarks
410
+ * Only the target is redirected. An edge whose SOURCE is a collapsed candidate
411
+ * stays untouched and is still rejected by {@link
412
+ * MemoryIngestOrchestrator._validateEdges}: sources are the records an edge is
413
+ * written ONTO, a collapsed candidate is never written, and the relation
414
+ * extractor is only ever offered writable candidates as edge sources in the
415
+ * first place. Silently relocating such an edge onto an existing record would
416
+ * attribute a link the host never asked for — the loud failure is correct there.
417
+ */
418
+ static _redirectEdges(edges, redirects) {
419
+ if (redirects.size === 0) {
420
+ return edges;
421
+ }
422
+ return edges.map((e) => {
423
+ const to = redirects.get((0, types_1.edgeTargetKey)(e.edge.target));
424
+ return to === undefined ? e : Object.assign(Object.assign({}, e), { edge: Object.assign(Object.assign({}, e.edge), { target: to }) });
425
+ });
331
426
  }
332
427
  /**
333
428
  * Validate stage-5 edges: each `source` must be a candidate being written; each
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../../src/packlets/ingest/orchestrator.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport { Hash, Logging, Result, fail, mapResults, succeed } from '@fgv/ts-utils';\nimport {\n Convert,\n EntityId,\n IEdge,\n IEdgeTarget,\n IIdentityCodec,\n IIdentityCodecResult,\n IMemoryEnvelope,\n IMemoryRecord,\n IProvenance,\n Kind,\n LinkType,\n MemoryId,\n MemoryScopeKey,\n Tag,\n edgeTargetKey,\n isTemporalRecord,\n isVersionCurrent\n} from '../types';\nimport { IBodyConverterRegistry } from '../converters';\nimport { IMemoryStore } from '../store';\nimport { IVectorIndex, MemoryEmbedder } from '../vector';\nimport { ICycleGuardEdge, assertNoCycles } from './cycleGuard';\nimport {\n IEntityResolver,\n IFactExtractor,\n IMemoryClassifier,\n IRelationCandidate,\n IRelationExtractor\n} from './hostStages';\nimport {\n ICandidateEdge,\n ICandidateRecord,\n IEntityResolutionCandidate,\n IIngestItem,\n IIngestItemResult,\n IIngestedRecordResult,\n IMemoryClassification,\n IngestDisposition,\n ResolutionVerdict\n} from './model';\n\n/**\n * The provenance source stamped on every record the ingest pipeline writes.\n * @public\n */\nexport const HOST_INGEST_PROVENANCE_SOURCE: string = 'host-ingest';\n\n/**\n * The link type whose presence on a temporal-kind candidate fires the\n * contradicts→temporal-versioned interlock.\n * @public\n */\nexport const CONTRADICTS_LINK_TYPE: LinkType = 'contradicts' as LinkType;\n\n/**\n * The default stage-4 layer-2 cosine similarity threshold (design note §2). A\n * near-duplicate candidate is surfaced to the {@link IEntityResolver} only when\n * its nearest neighbor scores `>= 0.85`.\n * @public\n */\nexport const DEFAULT_SIMILARITY_THRESHOLD: number = 0.85;\n\n/**\n * The default top-K for stage-4 layer-2 similarity candidate generation.\n * @public\n */\nexport const DEFAULT_SIMILARITY_TOP_K: number = 5;\n\n/**\n * How the write-time cycle guard behaves: `'reject'` (default — a cycle-inducing\n * edge fails the ingest) or `'off'` (no acyclicity constraint, for deployments\n * whose link graphs are legitimately cyclic — e.g. mutual associative links).\n * @public\n */\nexport type CycleGuardMode = 'reject' | 'off';\n\n/**\n * The fgv-owned six-stage ingest orchestrator. Composes the host's staged\n * classify / extract / (optional) resolve / relate machinery around fgv's owned\n * validation boundary, dedup, edge + cycle safety, provenance stamping, and the\n * contradicts→temporal interlock.\n * @public\n */\nexport interface IMemoryIngestOrchestrator {\n /**\n * Ingest a SINGLE item end-to-end (the first-class per-turn streaming path).\n */\n ingestItem(item: IIngestItem): Promise<Result<IIngestItemResult>>;\n\n /**\n * Ingest a batch of items. A convenience loop over {@link\n * IMemoryIngestOrchestrator.ingestItem | ingestItem} — items are processed in\n * order and the first failure aborts the batch.\n */\n ingestBatch(items: ReadonlyArray<IIngestItem>): Promise<Result<ReadonlyArray<IIngestItemResult>>>;\n}\n\n/**\n * Parameters for {@link MemoryIngestOrchestrator.create}.\n * @public\n */\nexport interface IMemoryIngestOrchestratorCreateParams {\n /** The store every write bottoms out in (stage 6). */\n readonly store: IMemoryStore;\n /** Per-kind body converter registry — the stage-3 typed validation boundary. */\n readonly registry: IBodyConverterRegistry;\n /** Per-kind identity codecs (maps a candidate `entityId` to its storage address). */\n readonly codecs?: ReadonlyMap<Kind, IIdentityCodec>;\n /** Default identity codec for kinds without an explicit entry. */\n readonly defaultCodec?: IIdentityCodec;\n /** Stage 2 — the host's classifier. */\n readonly classifier: IMemoryClassifier;\n /** Stage 3 — the host's fact extractor. */\n readonly extractor: IFactExtractor;\n /** Stage 5 — the host's relation extractor. */\n readonly relationExtractor: IRelationExtractor;\n /**\n * Stage 4 (optional, OQ-13) — the host's entity resolver. Absent → stage-4\n * dedup is exact-`{ kind, body }`-hash only (the deterministic-identity path).\n */\n readonly entityResolver?: IEntityResolver;\n /**\n * Optional vector index for stage-4 layer-2 similarity candidate-gen. Wired\n * together with {@link IMemoryIngestOrchestratorCreateParams.embed | embed} AND\n * {@link IMemoryIngestOrchestratorCreateParams.entityResolver | entityResolver};\n * absent (or either co-requisite absent) → layer-2 is skipped and dedup is\n * exact-only.\n */\n readonly vectorIndex?: IVectorIndex;\n /** Optional embedder used to embed a candidate for layer-2 similarity search. */\n readonly embed?: MemoryEmbedder;\n /**\n * Stage-4 layer-2 cosine threshold. Defaults to {@link\n * DEFAULT_SIMILARITY_THRESHOLD} (`0.85`).\n */\n readonly similarityThreshold?: number;\n /**\n * Stage-4 layer-2 top-K. Defaults to {@link DEFAULT_SIMILARITY_TOP_K} (`5`).\n */\n readonly similarityTopK?: number;\n /** Write-time cycle guard mode. Defaults to `'reject'`. */\n readonly cycleGuard?: CycleGuardMode;\n /** Diagnostic logger (defaults to a no-op). */\n readonly logger?: Logging.ILogger;\n}\n\n/** The fully-wired stage-4 layer-2 dependencies (present only when all three are supplied). */\ninterface ISimilarityWiring {\n readonly resolver: IEntityResolver;\n readonly vectorIndex: IVectorIndex;\n readonly embed: MemoryEmbedder;\n}\n\n/** A snapshot record paired with its resolved scope-qualified `(scope, id)` address. */\ninterface IScopedRecord {\n readonly address: IEdgeTarget;\n readonly record: IMemoryRecord<unknown>;\n}\n\n/** Internal per-candidate plan threaded through the pipeline. */\ninterface ICandidatePlan {\n readonly candidate: ICandidateRecord;\n /** The write target's storage address (re-addressed to the target for merge-into). */\n readonly writeAddress: IIdentityCodecResult;\n /** The write target's entity id (re-addressed for merge-into). */\n readonly writeEntityId: EntityId;\n /** The reference id used in stage-5 edges (the write target's `idStem`). */\n readonly refId: MemoryId;\n /**\n * The scope-qualified reference used in stage-5 edges: the write target's\n * `(scope, idStem)`. Stage-5 sources / dedup all key on this scoped address so\n * two candidates that share a stem across scopes never collide.\n */\n readonly refTarget: IEdgeTarget;\n /** The resolution verdict; carries the target id on its target-bearing arms. */\n readonly verdict: ResolutionVerdict;\n /**\n * The pre-ingest target record for a `merge-into` write — its existing\n * `tags` / `links` / `provenance` are UNIONed with the candidate's at stage 6\n * so a wholesale-replace merge never wipes them.\n */\n readonly mergeTarget?: IMemoryRecord<unknown>;\n}\n\n/**\n * Default {@link IMemoryIngestOrchestrator}.\n * @public\n */\nexport class MemoryIngestOrchestrator implements IMemoryIngestOrchestrator {\n private readonly _store: IMemoryStore;\n private readonly _registry: IBodyConverterRegistry;\n private readonly _codecs: ReadonlyMap<Kind, IIdentityCodec>;\n private readonly _defaultCodec: IIdentityCodec | undefined;\n private readonly _classifier: IMemoryClassifier;\n private readonly _extractor: IFactExtractor;\n private readonly _relationExtractor: IRelationExtractor;\n private readonly _similarity: ISimilarityWiring | undefined;\n private readonly _similarityThreshold: number;\n private readonly _similarityTopK: number;\n private readonly _cycleGuard: CycleGuardMode;\n private readonly _logger: Logging.ILogger;\n private readonly _hasher: Hash.Crc32Normalizer;\n\n private constructor(params: IMemoryIngestOrchestratorCreateParams) {\n this._store = params.store;\n this._registry = params.registry;\n this._codecs = params.codecs ?? new Map<Kind, IIdentityCodec>();\n this._defaultCodec = params.defaultCodec;\n this._classifier = params.classifier;\n this._extractor = params.extractor;\n this._relationExtractor = params.relationExtractor;\n this._similarity =\n params.entityResolver !== undefined && params.vectorIndex !== undefined && params.embed !== undefined\n ? { resolver: params.entityResolver, vectorIndex: params.vectorIndex, embed: params.embed }\n : undefined;\n this._similarityThreshold = params.similarityThreshold ?? DEFAULT_SIMILARITY_THRESHOLD;\n this._similarityTopK = params.similarityTopK ?? DEFAULT_SIMILARITY_TOP_K;\n this._cycleGuard = params.cycleGuard ?? 'reject';\n this._logger = params.logger ?? new Logging.NoOpLogger();\n this._hasher = new Hash.Crc32Normalizer();\n }\n\n /** Family-convention factory. */\n public static create(params: IMemoryIngestOrchestratorCreateParams): Result<MemoryIngestOrchestrator> {\n return succeed(new MemoryIngestOrchestrator(params));\n }\n\n /** {@inheritDoc IMemoryIngestOrchestrator.ingestItem} */\n public async ingestItem(item: IIngestItem): Promise<Result<IIngestItemResult>> {\n return (await this._classify(item))\n .thenOnSuccess((classification) => this._extract(item, classification))\n .thenOnSuccess((candidates) => this._processCandidates(item, candidates));\n }\n\n /** {@inheritDoc IMemoryIngestOrchestrator.ingestBatch} */\n public async ingestBatch(\n items: ReadonlyArray<IIngestItem>\n ): Promise<Result<ReadonlyArray<IIngestItemResult>>> {\n const results: IIngestItemResult[] = [];\n for (const item of items) {\n const result: Result<IIngestItemResult> = await this.ingestItem(item);\n if (result.isFailure()) {\n return fail(result.message);\n }\n results.push(result.value);\n }\n return succeed(results);\n }\n\n /** Stage 2 — classify (host), normalizing a rejected promise into a Failure. */\n private async _classify(item: IIngestItem): Promise<Result<IMemoryClassification>> {\n return this._capture(() => this._classifier.classify(item), `ingest '${item.id}': classify`);\n }\n\n /** Stage 3 — extract (host), normalizing a rejected promise into a Failure. */\n private async _extract(\n item: IIngestItem,\n classification: IMemoryClassification\n ): Promise<Result<ReadonlyArray<ICandidateRecord>>> {\n return this._capture(() => this._extractor.extract(item, classification), `ingest '${item.id}': extract`);\n }\n\n /**\n * Stages 3b-6 over the extracted candidates: validate bodies, resolve/dedup\n * (stage 4), relate + cycle guard (stage 5), and load-with-provenance (stage 6).\n */\n private async _processCandidates(\n item: IIngestItem,\n candidates: ReadonlyArray<ICandidateRecord>\n ): Promise<Result<IIngestItemResult>> {\n // Snapshot the store once; stage-4 resolution and the cycle guard reason over\n // the pre-ingest state.\n const snapshotResult: Result<ReadonlyArray<IMemoryRecord<unknown>>> = await this._store.list();\n if (snapshotResult.isFailure()) {\n return fail(`ingest '${item.id}': failed to snapshot store: ${snapshotResult.message}`);\n }\n const snapshot: ReadonlyArray<IMemoryRecord<unknown>> = snapshotResult.value;\n // Resolve every snapshot record's scope-qualified address ONCE, then index it\n // by the canonical scoped key. The single `byKey` view drives BOTH the edge\n // path (validation + cycle guard) AND the verdict/similarity target lookups —\n // so a filename stem reused across scopes never aliases on any path.\n const scopedResult: Result<ReadonlyArray<IScopedRecord>> = this._scopeRecords(snapshot);\n if (scopedResult.isFailure()) {\n return fail(`ingest '${item.id}': ${scopedResult.message}`);\n }\n const scoped: ReadonlyArray<IScopedRecord> = scopedResult.value;\n const byKey: ReadonlyMap<string, IMemoryRecord<unknown>> = new Map<string, IMemoryRecord<unknown>>(\n scoped.map((s) => [edgeTargetKey(s.address), s.record])\n );\n\n // Stage 3b + 4: validate each body and resolve a verdict/plan.\n const plans: ICandidatePlan[] = [];\n for (const candidate of candidates) {\n const planResult: Result<ICandidatePlan> = await this._planCandidate(item, candidate, snapshot, byKey);\n if (planResult.isFailure()) {\n return fail(planResult.message);\n }\n plans.push(planResult.value);\n }\n\n // Stage 5: relate over the writable candidates, validate + cycle-guard.\n const writablePlans: ICandidatePlan[] = plans.filter((plan) => plan.verdict.verdict !== 'duplicate-of');\n const edgesResult: Result<ReadonlyArray<ICandidateEdge>> = await this._relate(\n item,\n writablePlans,\n scoped,\n byKey\n );\n if (edgesResult.isFailure()) {\n return fail(edgesResult.message);\n }\n const edges: ReadonlyArray<ICandidateEdge> = edgesResult.value;\n\n // Stage 6: load-with-provenance, in extraction order.\n const records: IIngestedRecordResult[] = [];\n for (const plan of plans) {\n const outcome: Result<IIngestedRecordResult> = await this._loadCandidate(item, plan, edges);\n if (outcome.isFailure()) {\n return fail(outcome.message);\n }\n records.push(outcome.value);\n }\n return succeed({ item, records });\n }\n\n /** Stage 3b + 4 for one candidate: validate body, resolve address, resolve verdict. */\n private async _planCandidate(\n item: IIngestItem,\n candidate: ICandidateRecord,\n snapshot: ReadonlyArray<IMemoryRecord<unknown>>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ICandidatePlan>> {\n const kind: Kind = candidate.envelope.kind;\n // Stage 3b: the typed validation boundary — no unchecked host body reaches the store.\n const bodyResult: Result<string> = this._registry\n .convert(kind, candidate.body)\n .withErrorFormat((msg) => `ingest '${item.id}': candidate body for kind '${kind}' is invalid: ${msg}`)\n .onSuccess(() => MemoryIngestOrchestrator._asStringBody(item, candidate));\n if (bodyResult.isFailure()) {\n return fail(bodyResult.message);\n }\n const body: string = bodyResult.value;\n\n const addrResult: Result<IIdentityCodecResult> = this._resolveAddress(candidate.envelope.entityId, kind);\n if (addrResult.isFailure()) {\n return fail(`ingest '${item.id}': ${addrResult.message}`);\n }\n const addr: IIdentityCodecResult = addrResult.value;\n\n return (await this._resolveVerdict(candidate, kind, body, addr, snapshot, byKey)).onSuccess((verdict) =>\n this._planFromVerdict(item, candidate, addr, verdict, byKey)\n );\n }\n\n /**\n * Turn a resolved verdict into a candidate plan. A `new` verdict writes under the\n * candidate's own address. Every TARGET-bearing verdict\n * (`duplicate-of` / `supersede` / `merge-into`) is validated uniformly: the\n * target must be a real store record (fgv owns validation — a non-compliant host\n * resolver never smuggles a bogus id through) AND its kind must equal the\n * candidate's kind (a cross-kind target would write to the wrong scope). Only\n * `merge-into` re-addresses the write to the target's entity.\n */\n private _planFromVerdict(\n item: IIngestItem,\n candidate: ICandidateRecord,\n addr: IIdentityCodecResult,\n verdict: ResolutionVerdict,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Result<ICandidatePlan> {\n if (verdict.verdict === 'new') {\n return Convert.memoryId.convert(addr.idStem).onSuccess((refId) =>\n succeed({\n candidate,\n writeAddress: addr,\n writeEntityId: candidate.envelope.entityId,\n refId,\n refTarget: { scope: addr.scope, id: refId },\n verdict\n })\n );\n }\n // duplicate-of | supersede | merge-into: the target must exist and share the\n // candidate's kind. Lookup is on the canonical scoped key, so a stem reused\n // across scopes binds only the record the verdict actually named.\n const target: IMemoryRecord<unknown> | undefined = byKey.get(edgeTargetKey(verdict.target));\n if (target === undefined) {\n return fail(\n `ingest '${item.id}': ${verdict.verdict} target '${MemoryIngestOrchestrator._formatTarget(\n verdict.target\n )}' does not exist in the store`\n );\n }\n if (target.envelope.kind !== candidate.envelope.kind) {\n return fail(\n `ingest '${item.id}': ${verdict.verdict} target '${MemoryIngestOrchestrator._formatTarget(\n verdict.target\n )}' is kind '${target.envelope.kind}' but the candidate is kind '${candidate.envelope.kind}'`\n );\n }\n if (verdict.verdict === 'merge-into') {\n // Re-address the write to the target's entity, carrying the target record so\n // stage 6 can UNION its existing tags/links (never overwrite them).\n const targetEntityId: EntityId = target.envelope.entityId;\n // The merge target is a snapshot record, and `_scopeRecords` already proved\n // every snapshot record's address resolves before planning runs — so this\n // re-resolve (needed for the full codec result: scope + idStem + isVersioned)\n // cannot fail. No error-context wrap is warranted; a failure here would be a\n // logic contradiction, not a user-facing condition.\n return this._resolveAddress(targetEntityId, target.envelope.kind).onSuccess((targetAddr) =>\n Convert.memoryId.convert(targetAddr.idStem).onSuccess((refId) =>\n succeed({\n candidate,\n writeAddress: targetAddr,\n writeEntityId: targetEntityId,\n refId,\n refTarget: { scope: targetAddr.scope, id: refId },\n verdict,\n mergeTarget: target\n })\n )\n );\n }\n // duplicate-of | supersede: write under the candidate's own address.\n return Convert.memoryId.convert(addr.idStem).onSuccess((refId) =>\n succeed({\n candidate,\n writeAddress: addr,\n writeEntityId: candidate.envelope.entityId,\n refId,\n refTarget: { scope: addr.scope, id: refId },\n verdict\n })\n );\n }\n\n /**\n * Stage 4 — resolve a dedup verdict. Layer 1: an exact `{ kind, body }` match in\n * the candidate's scope is a `duplicate-of` (design note §1). Layer 2 (only when\n * a resolver + vector index + embedder are all wired): embed the candidate,\n * surface over-threshold neighbors, and dispatch to the {@link IEntityResolver}.\n * Otherwise the verdict is `new` (the exact-only fall-back path).\n */\n private async _resolveVerdict(\n candidate: ICandidateRecord,\n kind: Kind,\n body: string,\n addr: IIdentityCodecResult,\n snapshot: ReadonlyArray<IMemoryRecord<unknown>>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ResolutionVerdict>> {\n return this._findExactMatch(kind, body, addr.scope, snapshot).thenOnSuccess(async (matchId) => {\n if (matchId !== undefined) {\n // The exact-match cohort is filtered to `addr.scope`, so the match lives\n // under that scope — its scope-qualified target is `(addr.scope, matchId)`.\n return succeed({ verdict: 'duplicate-of', target: { scope: addr.scope, id: matchId } });\n }\n const layer2: ISimilarityWiring | undefined = this._similarity;\n if (layer2 === undefined) {\n // No layer-2: exact-only fall-back (the deterministic-identity host path).\n return succeed({ verdict: 'new' });\n }\n return this._resolveViaSimilarity(candidate, addr, body, layer2, byKey);\n });\n }\n\n /** Layer-2 similarity candidate-gen + resolver dispatch. */\n private async _resolveViaSimilarity(\n candidate: ICandidateRecord,\n addr: IIdentityCodecResult,\n body: string,\n wiring: ISimilarityWiring,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ResolutionVerdict>> {\n return MemoryIngestOrchestrator._provisionalRecord(candidate, addr.idStem, body).thenOnSuccess(\n (provisional) => this._resolveViaSimilarityEmbedded(candidate, addr, wiring, byKey, provisional)\n );\n }\n\n /** Layer-2 continuation once the candidate has a provisional record to embed. */\n private async _resolveViaSimilarityEmbedded(\n candidate: ICandidateRecord,\n addr: IIdentityCodecResult,\n wiring: ISimilarityWiring,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>,\n provisional: IMemoryRecord<unknown>\n ): Promise<Result<ResolutionVerdict>> {\n const embedded: Result<Float32Array> = await this._capture(\n () => wiring.embed(provisional),\n `ingest '${candidate.envelope.entityId}': embed candidate`\n );\n if (embedded.isFailure()) {\n return fail(embedded.message);\n }\n const queried = await this._capture(\n () => wiring.vectorIndex.query(embedded.value, this._similarityTopK),\n `ingest '${candidate.envelope.entityId}': similarity query`\n );\n if (queried.isFailure()) {\n return fail(queried.message);\n }\n const similar: IEntityResolutionCandidate[] = [];\n for (const hit of queried.value) {\n // Skip below-threshold hits and the candidate's OWN scope-qualified address\n // (a re-ingest of the same entity must not dedup against its prior version).\n // Both the scope AND the id must match to be \"self\" — a same-stem record in\n // another scope is a legitimate distinct neighbor. This field-equality is\n // exactly equivalent to comparing `edgeTargetKey(hit.target)` against the\n // candidate's own key (edgeTargetKey is pure and injective on `(scope, id)`),\n // so this one site reads the components directly rather than re-keying.\n const isSelf: boolean = hit.target.scope === addr.scope && hit.target.id === addr.idStem;\n if (hit.score < this._similarityThreshold || isSelf) {\n continue;\n }\n const record: IMemoryRecord<unknown> | undefined = byKey.get(edgeTargetKey(hit.target));\n if (record !== undefined) {\n similar.push({ target: hit.target, record, score: hit.score });\n }\n }\n if (similar.length === 0) {\n return succeed({ verdict: 'new' });\n }\n return this._capture(\n () => wiring.resolver.resolve(candidate, similar),\n `ingest '${candidate.envelope.entityId}': resolve`\n );\n }\n\n /**\n * Find an existing record in `scope` whose `{ kind, body }` hash matches the\n * candidate's (layer-1 exact dedup). Invalidated temporal versions are excluded\n * — only a live (non-temporal or current) record deduplicates a candidate.\n */\n private _findExactMatch(\n kind: Kind,\n body: string,\n scope: MemoryScopeKey,\n snapshot: ReadonlyArray<IMemoryRecord<unknown>>\n ): Result<MemoryId | undefined> {\n // Same-kind, same-scope, LIVE (non-temporal or current) records are the exact\n // cohort. `_resolveAddress(...).map(...).orDefault()` collapses an unresolved\n // codec to a non-matching scope with no explicit failure branch.\n const cohort: ReadonlyArray<IMemoryRecord<unknown>> = snapshot.filter(\n (record) =>\n record.envelope.kind === kind &&\n !(isTemporalRecord(record) && !isVersionCurrent(record)) &&\n this._resolveAddress(record.envelope.entityId, record.envelope.kind)\n .onSuccess((addr) => succeed(addr.scope))\n .orDefault() === scope\n );\n return this._exactKey(kind, body).onSuccess((key) =>\n mapResults(\n cohort.map((record) =>\n MemoryIngestOrchestrator._recordBodyString(record).onSuccess((recordBody) =>\n this._exactKey(record.envelope.kind, recordBody).onSuccess((recordKey) =>\n succeed({ id: record.envelope.id, key: recordKey })\n )\n )\n )\n ).onSuccess((keyed) => succeed(keyed.find((entry) => entry.key === key)?.id))\n );\n }\n\n /**\n * The body of a persisted record, required to be a string (the store persists\n * only string bodies). Fails loudly rather than blind-casting an `unknown` body\n * into the exact-dedup hash — a non-string existing body is a store-integrity\n * fault, surfaced with context, not a silent miscompute.\n */\n private static _recordBodyString(record: IMemoryRecord<unknown>): Result<string> {\n if (typeof record.body !== 'string') {\n return fail(\n `ingest: stored record '${record.envelope.id}' has a non-string body (got ${typeof record.body})`\n );\n }\n return succeed(record.body);\n }\n\n /** The stage-4 exact-dedup key over `{ kind, body }` (design note §1). */\n private _exactKey(kind: Kind, body: string): Result<string> {\n return this._hasher.computeHash({ kind, body });\n }\n\n /** Stage 5 — relate (host), validate edges, and run the write-time cycle guard. */\n private async _relate(\n item: IIngestItem,\n writablePlans: ReadonlyArray<ICandidatePlan>,\n scoped: ReadonlyArray<IScopedRecord>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ReadonlyArray<ICandidateEdge>>> {\n const relationCandidates: IRelationCandidate[] = writablePlans.map((plan) => ({\n candidate: plan.candidate,\n id: plan.refTarget\n }));\n const proposed: Result<ReadonlyArray<ICandidateEdge>> = await this._capture(\n () => this._relationExtractor.relate({ item, candidates: relationCandidates }),\n `ingest '${item.id}': relate`\n );\n if (proposed.isFailure()) {\n return proposed;\n }\n // refIds and the existing-record view (`byKey`, shared with the verdict path)\n // both key on the canonical scoped address, so a stem reused across scopes\n // never aliases.\n const refIds: ReadonlySet<string> = new Set<string>(\n writablePlans.map((plan) => edgeTargetKey(plan.refTarget))\n );\n const validation: Result<true> = this._validateEdges(item, proposed.value, refIds, byKey);\n if (validation.isFailure()) {\n return fail(validation.message);\n }\n if (this._cycleGuard === 'reject') {\n const guard: Result<true> = assertNoCycles(\n MemoryIngestOrchestrator._existingEdges(scoped),\n proposed.value.map((e) => ({ source: e.source, target: e.edge.target, type: e.edge.type }))\n );\n if (guard.isFailure()) {\n return fail(`ingest '${item.id}': ${guard.message}`);\n }\n }\n return succeed(proposed.value);\n }\n\n /**\n * Validate stage-5 edges: each `source` must be a candidate being written; each\n * `target` must resolve to a sibling candidate or an existing store record. All\n * matching is on the canonical scope-qualified address.\n */\n private _validateEdges(\n item: IIngestItem,\n edges: ReadonlyArray<ICandidateEdge>,\n refIds: ReadonlySet<string>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Result<true> {\n return mapResults(\n edges.map((edge) => {\n if (!refIds.has(edgeTargetKey(edge.source))) {\n return fail(\n `ingest '${item.id}': edge source '${MemoryIngestOrchestrator._formatTarget(\n edge.source\n )}' is not a candidate being written`\n );\n }\n const targetKey: string = edgeTargetKey(edge.edge.target);\n if (!refIds.has(targetKey) && byKey.get(targetKey) === undefined) {\n return fail(\n `ingest '${item.id}': edge target '${MemoryIngestOrchestrator._formatTarget(\n edge.edge.target\n )}' resolves to neither a sibling candidate nor an existing record`\n );\n }\n return succeed(true);\n })\n ).onSuccess(() => succeed(true));\n }\n\n /** Stage 6 — stamp provenance + edges, admit through the store, record the outcome. */\n private async _loadCandidate(\n item: IIngestItem,\n plan: ICandidatePlan,\n allEdges: ReadonlyArray<ICandidateEdge>\n ): Promise<Result<IIngestedRecordResult>> {\n const refKey: string = edgeTargetKey(plan.refTarget);\n const myEdges: ReadonlyArray<ICandidateEdge> = allEdges.filter((e) => edgeTargetKey(e.source) === refKey);\n if (plan.verdict.verdict === 'duplicate-of') {\n // No write: the existing target satisfied the candidate. The target id is a\n // typed field of the narrowed `duplicate-of` verdict — no cast, no guard.\n return succeed({\n candidate: plan.candidate,\n resolution: plan.verdict,\n disposition: 'deduped',\n id: plan.verdict.target.id,\n edges: myEdges\n });\n }\n return this._buildRecord(item, plan, myEdges).thenOnSuccess(async (record) =>\n (await this._store.put(record))\n .withErrorFormat((msg) => `ingest '${item.id}': write failed: ${msg}`)\n .onSuccess((persisted) => {\n const disposition: IngestDisposition = plan.verdict.verdict === 'merge-into' ? 'merged' : 'written';\n const interlock: 'temporal-versioned' | undefined =\n plan.writeAddress.isVersioned && myEdges.some((e) => e.edge.type === CONTRADICTS_LINK_TYPE)\n ? 'temporal-versioned'\n : undefined;\n return succeed({\n candidate: plan.candidate,\n resolution: plan.verdict,\n disposition,\n id: persisted.envelope.id,\n record: persisted,\n edges: myEdges,\n ...(interlock !== undefined ? { interlock } : {})\n });\n })\n );\n }\n\n /** Build the fully-stamped record to persist (provenance + edges + placeholder txn fields). */\n private _buildRecord(\n item: IIngestItem,\n plan: ICandidatePlan,\n myEdges: ReadonlyArray<ICandidateEdge>\n ): Result<IMemoryRecord<unknown>> {\n const base: Omit<IMemoryEnvelope, 'id' | 'seq' | 'contentHash' | 'created' | 'updated'> =\n plan.candidate.envelope;\n // For merge-into the store's `applyUpdate` REPLACES array fields wholesale, so\n // the persisted envelope must already carry the UNION of the target's existing\n // tags/links/provenance and the candidate's — otherwise the merge silently\n // wipes the target's prior links/tags.\n const target: IMemoryRecord<unknown> | undefined = plan.mergeTarget;\n const priorLinks: ReadonlyArray<IEdge> = target !== undefined ? target.envelope.links : [];\n const priorTags: ReadonlyArray<Tag> = target !== undefined ? target.envelope.tags : [];\n const priorProvenance: IProvenance = target !== undefined ? target.envelope.provenance : { source: '' };\n return Convert.memoryId.convert(plan.writeAddress.idStem).onSuccess((id) =>\n // Dedup the combined links by canonical edge key: the target's prior links, the\n // candidate's own links, and the stage-5 edges (two candidates that resolve\n // merge-into the SAME target share a `refId` — hence the same `myEdges` — and a\n // relation extractor may repeat an edge) each appear exactly once.\n this._dedupEdges([...priorLinks, ...base.links, ...myEdges.map((e) => e.edge)]).onSuccess((links) => {\n const provenance: IProvenance = {\n // Preserve the target's provenance extension keys, overlay the candidate's,\n // then stamp the host-ingest source + derivedFrom (target present only for\n // merge-into; otherwise the seed is inert).\n ...(target !== undefined ? priorProvenance : {}),\n ...base.provenance,\n source: HOST_INGEST_PROVENANCE_SOURCE,\n ...(item.sourceId !== undefined ? { derivedFrom: item.sourceId } : {})\n };\n const envelope: IMemoryEnvelope = {\n ...base,\n id,\n entityId: plan.writeEntityId,\n seq: 0,\n contentHash: '',\n created: 0,\n updated: 0,\n provenance,\n tags: MemoryIngestOrchestrator._unionTags(priorTags, base.tags),\n links\n };\n return succeed({ envelope, body: plan.candidate.body });\n })\n );\n }\n\n /** Union two tag lists, de-duplicated, preserving first-occurrence order. */\n private static _unionTags(prior: ReadonlyArray<Tag>, incoming: ReadonlyArray<Tag>): ReadonlyArray<Tag> {\n const seen: Set<string> = new Set<string>();\n const out: Tag[] = [];\n for (const tag of [...prior, ...incoming]) {\n if (!seen.has(tag)) {\n seen.add(tag);\n out.push(tag);\n }\n }\n return out;\n }\n\n /** De-duplicate a link list by canonical edge hash, preserving first-occurrence order. */\n private _dedupEdges(edges: ReadonlyArray<IEdge>): Result<ReadonlyArray<IEdge>> {\n const seen: Set<string> = new Set<string>();\n const deduped: IEdge[] = [];\n return mapResults(\n edges.map((edge) =>\n this._hasher.computeHash(edge).onSuccess((key) => {\n if (!seen.has(key)) {\n seen.add(key);\n deduped.push(edge);\n }\n return succeed(key);\n })\n )\n ).onSuccess(() => succeed(deduped));\n }\n\n /** Resolve a `(kind, entityId)` to its storage address via the registered codec. */\n private _resolveAddress(entityId: EntityId, kind: Kind): Result<IIdentityCodecResult> {\n const codec: IIdentityCodec | undefined = this._codecs.get(kind) ?? this._defaultCodec;\n if (codec === undefined) {\n return fail(`no identity codec registered for kind '${kind}'`);\n }\n return codec.encode(entityId);\n }\n\n /** Run a host hook, normalizing a thrown/rejected hook into a Failure (never throws across the seam). */\n private async _capture<T>(op: () => Promise<Result<T>>, label: string): Promise<Result<T>> {\n try {\n return await op();\n } catch (err) {\n const message: string = `${label} threw: ${String(err)}`;\n this._logger.warn(message);\n return fail(message);\n }\n }\n\n /**\n * Every existing outbound edge in the snapshot, as cycle-guard edges. The\n * source is the record's own scope-qualified address (already resolved by\n * {@link MemoryIngestOrchestrator._scopeRecords}); the target is the edge's\n * own scoped target. Both ends are scoped so the guard never conflates a stem\n * shared across scopes into one graph node.\n */\n private static _existingEdges(scoped: ReadonlyArray<IScopedRecord>): ReadonlyArray<ICycleGuardEdge> {\n const edges: ICycleGuardEdge[] = [];\n for (const s of scoped) {\n for (const edge of s.record.envelope.links) {\n edges.push({ source: s.address, target: edge.target, type: edge.type });\n }\n }\n return edges;\n }\n\n /**\n * Resolve every snapshot record's scope-qualified `(scope, id)` address via its\n * registered codec. Fails loudly if a record's kind has no resolvable codec —\n * the edge path cannot place an un-scopeable record in the graph, and a missing\n * codec for a stored kind is a real misconfiguration, not something to paper over.\n */\n private _scopeRecords(\n records: ReadonlyArray<IMemoryRecord<unknown>>\n ): Result<ReadonlyArray<IScopedRecord>> {\n return mapResults(\n records.map((record) =>\n this._resolveAddress(record.envelope.entityId, record.envelope.kind)\n .withErrorFormat((msg) => `cannot resolve scope for stored record '${record.envelope.id}': ${msg}`)\n .onSuccess((addr) => succeed({ address: { scope: addr.scope, id: record.envelope.id }, record }))\n )\n );\n }\n\n /** Human-readable `scope/id` rendering of a scoped target for edge-validation diagnostics. */\n private static _formatTarget(target: IEdgeTarget): string {\n return `${target.scope}/${target.id}`;\n }\n\n /** A provisional record for embedding a candidate (placeholder txn-time fields). */\n private static _provisionalRecord(\n candidate: ICandidateRecord,\n idStem: string,\n body: string\n ): Result<IMemoryRecord<unknown>> {\n return Convert.memoryId.convert(idStem).onSuccess((id) => {\n const envelope: IMemoryEnvelope = {\n ...candidate.envelope,\n id,\n seq: 0,\n contentHash: '',\n created: 0,\n updated: 0\n };\n return succeed({ envelope, body });\n });\n }\n\n /** Require a candidate body to be a string (the store persists only string bodies). */\n private static _asStringBody(item: IIngestItem, candidate: ICandidateRecord): Result<string> {\n if (typeof candidate.body !== 'string') {\n return fail(\n `ingest '${item.id}': candidate body for kind '${\n candidate.envelope.kind\n }' must be a string (got ${typeof candidate.body})`\n );\n }\n return succeed(candidate.body);\n }\n}\n"]}
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../../src/packlets/ingest/orchestrator.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport { Hash, Logging, Result, fail, mapResults, succeed } from '@fgv/ts-utils';\nimport {\n Convert,\n DedupScope,\n EntityId,\n IEdge,\n IEdgeTarget,\n IIdentityCodec,\n IIdentityCodecResult,\n IMemoryEnvelope,\n IMemoryRecord,\n IProvenance,\n Kind,\n LinkType,\n MemoryId,\n Tag,\n edgeTargetKey,\n isTemporalRecord,\n isVersionCurrent\n} from '../types';\nimport { IBodyConverterRegistry } from '../converters';\nimport { IMemoryStore } from '../store';\nimport { IVectorIndex, MemoryEmbedder } from '../vector';\nimport { ICycleGuardEdge, assertNoCycles } from './cycleGuard';\nimport {\n IEntityResolver,\n IFactExtractor,\n IMemoryClassifier,\n IRelationCandidate,\n IRelationExtractor\n} from './hostStages';\nimport {\n ICandidateEdge,\n ICandidateRecord,\n IEntityResolutionCandidate,\n IIngestItem,\n IIngestItemResult,\n IIngestedRecordResult,\n IMemoryClassification,\n IngestDisposition,\n ResolutionVerdict\n} from './model';\n\n/**\n * The provenance source stamped on every record the ingest pipeline writes.\n * @public\n */\nexport const HOST_INGEST_PROVENANCE_SOURCE: string = 'host-ingest';\n\n/**\n * The link type whose presence on a temporal-kind candidate fires the\n * contradicts→temporal-versioned interlock.\n * @public\n */\nexport const CONTRADICTS_LINK_TYPE: LinkType = 'contradicts' as LinkType;\n\n/**\n * The default stage-4 layer-2 cosine similarity threshold (design note §2). A\n * near-duplicate candidate is surfaced to the {@link IEntityResolver} only when\n * its nearest neighbor scores `>= 0.85`.\n * @public\n */\nexport const DEFAULT_SIMILARITY_THRESHOLD: number = 0.85;\n\n/**\n * The default top-K for stage-4 layer-2 similarity candidate generation.\n * @public\n */\nexport const DEFAULT_SIMILARITY_TOP_K: number = 5;\n\n/**\n * How the write-time cycle guard behaves: `'reject'` (default — a cycle-inducing\n * edge fails the ingest) or `'off'` (no acyclicity constraint, for deployments\n * whose link graphs are legitimately cyclic — e.g. mutual associative links).\n * @public\n */\nexport type CycleGuardMode = 'reject' | 'off';\n\n/**\n * The fgv-owned six-stage ingest orchestrator. Composes the host's staged\n * classify / extract / (optional) resolve / relate machinery around fgv's owned\n * validation boundary, dedup, edge + cycle safety, provenance stamping, and the\n * contradicts→temporal interlock.\n * @public\n */\nexport interface IMemoryIngestOrchestrator {\n /**\n * Ingest a SINGLE item end-to-end (the first-class per-turn streaming path).\n */\n ingestItem(item: IIngestItem): Promise<Result<IIngestItemResult>>;\n\n /**\n * Ingest a batch of items. A convenience loop over {@link\n * IMemoryIngestOrchestrator.ingestItem | ingestItem} — items are processed in\n * order and the first failure aborts the batch.\n */\n ingestBatch(items: ReadonlyArray<IIngestItem>): Promise<Result<ReadonlyArray<IIngestItemResult>>>;\n}\n\n/**\n * Parameters for {@link MemoryIngestOrchestrator.create}.\n * @public\n */\nexport interface IMemoryIngestOrchestratorCreateParams {\n /** The store every write bottoms out in (stage 6). */\n readonly store: IMemoryStore;\n /** Per-kind body converter registry — the stage-3 typed validation boundary. */\n readonly registry: IBodyConverterRegistry;\n /** Per-kind identity codecs (maps a candidate `entityId` to its storage address). */\n readonly codecs?: ReadonlyMap<Kind, IIdentityCodec>;\n /** Default identity codec for kinds without an explicit entry. */\n readonly defaultCodec?: IIdentityCodec;\n /** Stage 2 — the host's classifier. */\n readonly classifier: IMemoryClassifier;\n /** Stage 3 — the host's fact extractor. */\n readonly extractor: IFactExtractor;\n /** Stage 5 — the host's relation extractor. */\n readonly relationExtractor: IRelationExtractor;\n /**\n * Stage 4 (optional, OQ-13) — the host's entity resolver. Absent → stage-4\n * dedup is exact-`{ kind, body }`-hash only (the deterministic-identity path).\n */\n readonly entityResolver?: IEntityResolver;\n /**\n * Optional vector index for stage-4 layer-2 similarity candidate-gen. Wired\n * together with {@link IMemoryIngestOrchestratorCreateParams.embed | embed} AND\n * {@link IMemoryIngestOrchestratorCreateParams.entityResolver | entityResolver};\n * absent (or either co-requisite absent) → layer-2 is skipped and dedup is\n * exact-only.\n */\n readonly vectorIndex?: IVectorIndex;\n /** Optional embedder used to embed a candidate for layer-2 similarity search. */\n readonly embed?: MemoryEmbedder;\n /**\n * Stage-4 layer-2 cosine threshold. Defaults to {@link\n * DEFAULT_SIMILARITY_THRESHOLD} (`0.85`).\n */\n readonly similarityThreshold?: number;\n /**\n * Stage-4 layer-2 top-K. Defaults to {@link DEFAULT_SIMILARITY_TOP_K} (`5`).\n */\n readonly similarityTopK?: number;\n /** Write-time cycle guard mode. Defaults to `'reject'`. */\n readonly cycleGuard?: CycleGuardMode;\n /** Diagnostic logger (defaults to a no-op). */\n readonly logger?: Logging.ILogger;\n}\n\n/** The fully-wired stage-4 layer-2 dependencies (present only when all three are supplied). */\ninterface ISimilarityWiring {\n readonly resolver: IEntityResolver;\n readonly vectorIndex: IVectorIndex;\n readonly embed: MemoryEmbedder;\n}\n\n/** A snapshot record paired with its resolved scope-qualified `(scope, id)` address. */\ninterface IScopedRecord {\n readonly address: IEdgeTarget;\n readonly record: IMemoryRecord<unknown>;\n}\n\n/** Internal per-candidate plan threaded through the pipeline. */\ninterface ICandidatePlan {\n readonly candidate: ICandidateRecord;\n /** The write target's storage address (re-addressed to the target for merge-into). */\n readonly writeAddress: IIdentityCodecResult;\n /** The write target's entity id (re-addressed for merge-into). */\n readonly writeEntityId: EntityId;\n /** The reference id used in stage-5 edges (the write target's `idStem`). */\n readonly refId: MemoryId;\n /**\n * The scope-qualified reference used in stage-5 edges: the write target's\n * `(scope, idStem)`. Stage-5 sources / dedup all key on this scoped address so\n * two candidates that share a stem across scopes never collide.\n */\n readonly refTarget: IEdgeTarget;\n /** The resolution verdict; carries the target id on its target-bearing arms. */\n readonly verdict: ResolutionVerdict;\n /**\n * The pre-ingest target record for a `merge-into` write — its existing\n * `tags` / `links` / `provenance` are UNIONed with the candidate's at stage 6\n * so a wholesale-replace merge never wipes them.\n */\n readonly mergeTarget?: IMemoryRecord<unknown>;\n}\n\n/**\n * Default {@link IMemoryIngestOrchestrator}.\n * @public\n */\nexport class MemoryIngestOrchestrator implements IMemoryIngestOrchestrator {\n private readonly _store: IMemoryStore;\n private readonly _registry: IBodyConverterRegistry;\n private readonly _codecs: ReadonlyMap<Kind, IIdentityCodec>;\n private readonly _defaultCodec: IIdentityCodec | undefined;\n private readonly _classifier: IMemoryClassifier;\n private readonly _extractor: IFactExtractor;\n private readonly _relationExtractor: IRelationExtractor;\n private readonly _similarity: ISimilarityWiring | undefined;\n private readonly _similarityThreshold: number;\n private readonly _similarityTopK: number;\n private readonly _cycleGuard: CycleGuardMode;\n private readonly _logger: Logging.ILogger;\n private readonly _hasher: Hash.Crc32Normalizer;\n\n private constructor(params: IMemoryIngestOrchestratorCreateParams) {\n this._store = params.store;\n this._registry = params.registry;\n this._codecs = params.codecs ?? new Map<Kind, IIdentityCodec>();\n this._defaultCodec = params.defaultCodec;\n this._classifier = params.classifier;\n this._extractor = params.extractor;\n this._relationExtractor = params.relationExtractor;\n this._similarity =\n params.entityResolver !== undefined && params.vectorIndex !== undefined && params.embed !== undefined\n ? { resolver: params.entityResolver, vectorIndex: params.vectorIndex, embed: params.embed }\n : undefined;\n this._similarityThreshold = params.similarityThreshold ?? DEFAULT_SIMILARITY_THRESHOLD;\n this._similarityTopK = params.similarityTopK ?? DEFAULT_SIMILARITY_TOP_K;\n this._cycleGuard = params.cycleGuard ?? 'reject';\n this._logger = params.logger ?? new Logging.NoOpLogger();\n this._hasher = new Hash.Crc32Normalizer();\n }\n\n /** Family-convention factory. */\n public static create(params: IMemoryIngestOrchestratorCreateParams): Result<MemoryIngestOrchestrator> {\n return succeed(new MemoryIngestOrchestrator(params));\n }\n\n /** {@inheritDoc IMemoryIngestOrchestrator.ingestItem} */\n public async ingestItem(item: IIngestItem): Promise<Result<IIngestItemResult>> {\n return (await this._classify(item))\n .thenOnSuccess((classification) => this._extract(item, classification))\n .thenOnSuccess((candidates) => this._processCandidates(item, candidates));\n }\n\n /** {@inheritDoc IMemoryIngestOrchestrator.ingestBatch} */\n public async ingestBatch(\n items: ReadonlyArray<IIngestItem>\n ): Promise<Result<ReadonlyArray<IIngestItemResult>>> {\n const results: IIngestItemResult[] = [];\n for (const item of items) {\n const result: Result<IIngestItemResult> = await this.ingestItem(item);\n if (result.isFailure()) {\n return fail(result.message);\n }\n results.push(result.value);\n }\n return succeed(results);\n }\n\n /** Stage 2 — classify (host), normalizing a rejected promise into a Failure. */\n private async _classify(item: IIngestItem): Promise<Result<IMemoryClassification>> {\n return this._capture(() => this._classifier.classify(item), `ingest '${item.id}': classify`);\n }\n\n /** Stage 3 — extract (host), normalizing a rejected promise into a Failure. */\n private async _extract(\n item: IIngestItem,\n classification: IMemoryClassification\n ): Promise<Result<ReadonlyArray<ICandidateRecord>>> {\n return this._capture(() => this._extractor.extract(item, classification), `ingest '${item.id}': extract`);\n }\n\n /**\n * Stages 3b-6 over the extracted candidates: validate bodies, resolve/dedup\n * (stage 4), relate + cycle guard (stage 5), and load-with-provenance (stage 6).\n */\n private async _processCandidates(\n item: IIngestItem,\n candidates: ReadonlyArray<ICandidateRecord>\n ): Promise<Result<IIngestItemResult>> {\n // Snapshot the store once; stage-4 resolution and the cycle guard reason over\n // the pre-ingest state.\n const snapshotResult: Result<ReadonlyArray<IMemoryRecord<unknown>>> = await this._store.list();\n if (snapshotResult.isFailure()) {\n return fail(`ingest '${item.id}': failed to snapshot store: ${snapshotResult.message}`);\n }\n const snapshot: ReadonlyArray<IMemoryRecord<unknown>> = snapshotResult.value;\n // Resolve every snapshot record's scope-qualified address ONCE, then index it\n // by the canonical scoped key. The single `byKey` view drives BOTH the edge\n // path (validation + cycle guard) AND the verdict/similarity target lookups —\n // so a filename stem reused across scopes never aliases on any path.\n const scopedResult: Result<ReadonlyArray<IScopedRecord>> = this._scopeRecords(snapshot);\n if (scopedResult.isFailure()) {\n return fail(`ingest '${item.id}': ${scopedResult.message}`);\n }\n const scoped: ReadonlyArray<IScopedRecord> = scopedResult.value;\n const byKey: ReadonlyMap<string, IMemoryRecord<unknown>> = new Map<string, IMemoryRecord<unknown>>(\n scoped.map((s) => [edgeTargetKey(s.address), s.record])\n );\n\n // Stage 3b + 4: validate each body and resolve a verdict/plan.\n const plans: ICandidatePlan[] = [];\n for (const candidate of candidates) {\n const planResult: Result<ICandidatePlan> = await this._planCandidate(item, candidate, snapshot, byKey);\n if (planResult.isFailure()) {\n return fail(planResult.message);\n }\n plans.push(planResult.value);\n }\n\n // Stage 5: relate over the writable candidates, validate + cycle-guard.\n const writablePlans: ICandidatePlan[] = plans.filter((plan) => plan.verdict.verdict !== 'duplicate-of');\n const edgesResult: Result<ReadonlyArray<ICandidateEdge>> = await this._relate(\n item,\n writablePlans,\n MemoryIngestOrchestrator._collapseRedirects(plans),\n scoped,\n byKey\n );\n if (edgesResult.isFailure()) {\n return fail(edgesResult.message);\n }\n const edges: ReadonlyArray<ICandidateEdge> = edgesResult.value;\n\n // Stage 6: load-with-provenance, in extraction order.\n const records: IIngestedRecordResult[] = [];\n for (const plan of plans) {\n const outcome: Result<IIngestedRecordResult> = await this._loadCandidate(item, plan, edges);\n if (outcome.isFailure()) {\n return fail(outcome.message);\n }\n records.push(outcome.value);\n }\n return succeed({ item, records });\n }\n\n /** Stage 3b + 4 for one candidate: validate body, resolve address, resolve verdict. */\n private async _planCandidate(\n item: IIngestItem,\n candidate: ICandidateRecord,\n snapshot: ReadonlyArray<IMemoryRecord<unknown>>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ICandidatePlan>> {\n const kind: Kind = candidate.envelope.kind;\n // Stage 3b: the typed validation boundary — no unchecked host body reaches the store.\n const bodyResult: Result<string> = this._registry\n .convert(kind, candidate.body)\n .withErrorFormat((msg) => `ingest '${item.id}': candidate body for kind '${kind}' is invalid: ${msg}`)\n .onSuccess(() => MemoryIngestOrchestrator._asStringBody(item, candidate));\n if (bodyResult.isFailure()) {\n return fail(bodyResult.message);\n }\n const body: string = bodyResult.value;\n\n const addrResult: Result<IIdentityCodecResult> = this._resolveAddress(candidate.envelope.entityId, kind);\n if (addrResult.isFailure()) {\n return fail(`ingest '${item.id}': ${addrResult.message}`);\n }\n const addr: IIdentityCodecResult = addrResult.value;\n\n return (await this._resolveVerdict(candidate, kind, body, addr, snapshot, byKey)).onSuccess((verdict) =>\n this._planFromVerdict(item, candidate, addr, verdict, byKey)\n );\n }\n\n /**\n * Turn a resolved verdict into a candidate plan. A `new` verdict writes under the\n * candidate's own address. Every TARGET-bearing verdict\n * (`duplicate-of` / `supersede` / `merge-into`) is validated uniformly: the\n * target must be a real store record (fgv owns validation — a non-compliant host\n * resolver never smuggles a bogus id through) AND its kind must equal the\n * candidate's kind (a cross-kind target would write to the wrong scope). Only\n * `merge-into` re-addresses the write to the target's entity.\n */\n private _planFromVerdict(\n item: IIngestItem,\n candidate: ICandidateRecord,\n addr: IIdentityCodecResult,\n verdict: ResolutionVerdict,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Result<ICandidatePlan> {\n if (verdict.verdict === 'new') {\n return Convert.memoryId.convert(addr.idStem).onSuccess((refId) =>\n succeed({\n candidate,\n writeAddress: addr,\n writeEntityId: candidate.envelope.entityId,\n refId,\n refTarget: { scope: addr.scope, id: refId },\n verdict\n })\n );\n }\n // duplicate-of | supersede | merge-into: the target must exist and share the\n // candidate's kind. Lookup is on the canonical scoped key, so a stem reused\n // across scopes binds only the record the verdict actually named.\n const target: IMemoryRecord<unknown> | undefined = byKey.get(edgeTargetKey(verdict.target));\n if (target === undefined) {\n return fail(\n `ingest '${item.id}': ${verdict.verdict} target '${MemoryIngestOrchestrator._formatTarget(\n verdict.target\n )}' does not exist in the store`\n );\n }\n if (target.envelope.kind !== candidate.envelope.kind) {\n return fail(\n `ingest '${item.id}': ${verdict.verdict} target '${MemoryIngestOrchestrator._formatTarget(\n verdict.target\n )}' is kind '${target.envelope.kind}' but the candidate is kind '${candidate.envelope.kind}'`\n );\n }\n if (verdict.verdict === 'merge-into') {\n // Re-address the write to the target's entity, carrying the target record so\n // stage 6 can UNION its existing tags/links (never overwrite them).\n const targetEntityId: EntityId = target.envelope.entityId;\n // The merge target is a snapshot record, and `_scopeRecords` already proved\n // every snapshot record's address resolves before planning runs — so this\n // re-resolve (needed for the full codec result: scope + idStem + isVersioned)\n // cannot fail. No error-context wrap is warranted; a failure here would be a\n // logic contradiction, not a user-facing condition.\n return this._resolveAddress(targetEntityId, target.envelope.kind).onSuccess((targetAddr) =>\n Convert.memoryId.convert(targetAddr.idStem).onSuccess((refId) =>\n succeed({\n candidate,\n writeAddress: targetAddr,\n writeEntityId: targetEntityId,\n refId,\n refTarget: { scope: targetAddr.scope, id: refId },\n verdict,\n mergeTarget: target\n })\n )\n );\n }\n // duplicate-of | supersede: write under the candidate's own address.\n return Convert.memoryId.convert(addr.idStem).onSuccess((refId) =>\n succeed({\n candidate,\n writeAddress: addr,\n writeEntityId: candidate.envelope.entityId,\n refId,\n refTarget: { scope: addr.scope, id: refId },\n verdict\n })\n );\n }\n\n /**\n * Stage 4 — resolve a dedup verdict. Layer 1: an exact `{ kind, body }` match in\n * the candidate's scope is a `duplicate-of`, at the granularity the kind's\n * {@link DedupScope} declares — scope-wide for `'content'`, restricted to the\n * candidate's own entity for `'entity'` (design note §1). Layer 2 (only when\n * a resolver + vector index + embedder are all wired): embed the candidate,\n * surface over-threshold neighbors, and dispatch to the {@link IEntityResolver}.\n * Otherwise the verdict is `new` (the exact-only fall-back path).\n */\n private async _resolveVerdict(\n candidate: ICandidateRecord,\n kind: Kind,\n body: string,\n addr: IIdentityCodecResult,\n snapshot: ReadonlyArray<IMemoryRecord<unknown>>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ResolutionVerdict>> {\n return this._findExactMatch(kind, body, addr, snapshot).thenOnSuccess(async (matchId) => {\n if (matchId !== undefined) {\n // The exact-match cohort is filtered to `addr.scope`, so the match lives\n // under that scope — its scope-qualified target is `(addr.scope, matchId)`.\n return succeed({ verdict: 'duplicate-of', target: { scope: addr.scope, id: matchId } });\n }\n const layer2: ISimilarityWiring | undefined = this._similarity;\n if (layer2 === undefined) {\n // No layer-2: exact-only fall-back (the deterministic-identity host path).\n return succeed({ verdict: 'new' });\n }\n return this._resolveViaSimilarity(candidate, addr, body, layer2, byKey);\n });\n }\n\n /** Layer-2 similarity candidate-gen + resolver dispatch. */\n private async _resolveViaSimilarity(\n candidate: ICandidateRecord,\n addr: IIdentityCodecResult,\n body: string,\n wiring: ISimilarityWiring,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ResolutionVerdict>> {\n return MemoryIngestOrchestrator._provisionalRecord(candidate, addr.idStem, body).thenOnSuccess(\n (provisional) => this._resolveViaSimilarityEmbedded(candidate, addr, wiring, byKey, provisional)\n );\n }\n\n /** Layer-2 continuation once the candidate has a provisional record to embed. */\n private async _resolveViaSimilarityEmbedded(\n candidate: ICandidateRecord,\n addr: IIdentityCodecResult,\n wiring: ISimilarityWiring,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>,\n provisional: IMemoryRecord<unknown>\n ): Promise<Result<ResolutionVerdict>> {\n const embedded: Result<Float32Array | undefined> = await this._capture(\n () => wiring.embed(provisional),\n `ingest '${candidate.envelope.entityId}': embed candidate`\n );\n if (embedded.isFailure()) {\n return fail(embedded.message);\n }\n // The embedder deliberately declined this candidate, so there is no vector to\n // search with and layer-2 similarity dedup cannot run for it. That is the same\n // position as a search that found nothing similar — `'new'` — and not an\n // error: declining to embed a kind must not make it un-ingestable.\n if (embedded.value === undefined) {\n return succeed({ verdict: 'new' });\n }\n // Hoisted: the `undefined` check above does not narrow across the callback\n // boundary below, and a local keeps the non-null assertion out of the code.\n const vector: Float32Array = embedded.value;\n const queried = await this._capture(\n () => wiring.vectorIndex.query(vector, this._similarityTopK),\n `ingest '${candidate.envelope.entityId}': similarity query`\n );\n if (queried.isFailure()) {\n return fail(queried.message);\n }\n const similar: IEntityResolutionCandidate[] = [];\n for (const hit of queried.value) {\n // Skip below-threshold hits and the candidate's OWN scope-qualified address\n // (a re-ingest of the same entity must not dedup against its prior version).\n // Both the scope AND the id must match to be \"self\" — a same-stem record in\n // another scope is a legitimate distinct neighbor. This field-equality is\n // exactly equivalent to comparing `edgeTargetKey(hit.target)` against the\n // candidate's own key (edgeTargetKey is pure and injective on `(scope, id)`),\n // so this one site reads the components directly rather than re-keying.\n const isSelf: boolean = hit.target.scope === addr.scope && hit.target.id === addr.idStem;\n if (hit.score < this._similarityThreshold || isSelf) {\n continue;\n }\n const record: IMemoryRecord<unknown> | undefined = byKey.get(edgeTargetKey(hit.target));\n if (record !== undefined) {\n similar.push({ target: hit.target, record, score: hit.score });\n }\n }\n if (similar.length === 0) {\n return succeed({ verdict: 'new' });\n }\n return this._capture(\n () => wiring.resolver.resolve(candidate, similar),\n `ingest '${candidate.envelope.entityId}': resolve`\n );\n }\n\n /**\n * Find an existing record whose `{ kind, body }` hash matches the candidate's\n * (layer-1 exact dedup, design note §1). Invalidated temporal versions are\n * excluded — only a live (non-temporal or current) record deduplicates a\n * candidate.\n *\n * @remarks\n * The cohort's granularity is the kind's DECLARED {@link DedupScope}, read\n * through {@link IMemoryStore.dedupScopeFor} so this layer and the store's own\n * write path can never disagree:\n *\n * - `'content'` — every live same-kind record in the candidate's scope,\n * regardless of entity. A cross-id body collision IS a duplicate (the\n * knowledge family; unchanged behavior).\n * - `'entity'` — only records at the candidate's OWN entity address. Two\n * distinct entities with byte-identical bodies never collapse into one\n * another, which is what the declaration has always meant on the direct-put\n * path and now means here too.\n *\n * The same-id collapse itself remains the store's job — this layer only decides\n * whether a cross-id body collision is eligible to be a `duplicate-of` at all.\n */\n private _findExactMatch(\n kind: Kind,\n body: string,\n addr: IIdentityCodecResult,\n snapshot: ReadonlyArray<IMemoryRecord<unknown>>\n ): Result<MemoryId | undefined> {\n const dedupScope: DedupScope = this._store.dedupScopeFor(kind);\n // Same-kind, same-scope, LIVE (non-temporal or current) records are the exact\n // cohort, narrowed to the candidate's own entity address under `'entity'`\n // granularity. `_resolveAddress(...).orDefault()` collapses an unresolved\n // codec to `undefined` — a non-matching address — with no explicit failure\n // branch, exactly as the scope-only filter did before.\n const cohort: ReadonlyArray<IMemoryRecord<unknown>> = snapshot.filter((record) => {\n if (record.envelope.kind !== kind || (isTemporalRecord(record) && !isVersionCurrent(record))) {\n return false;\n }\n const recordAddr: IIdentityCodecResult | undefined = this._resolveAddress(\n record.envelope.entityId,\n record.envelope.kind\n ).orDefault();\n if (recordAddr === undefined || recordAddr.scope !== addr.scope) {\n return false;\n }\n return dedupScope === 'content' || recordAddr.idStem === addr.idStem;\n });\n return this._exactKey(kind, body).onSuccess((key) =>\n mapResults(\n cohort.map((record) =>\n MemoryIngestOrchestrator._recordBodyString(record).onSuccess((recordBody) =>\n this._exactKey(record.envelope.kind, recordBody).onSuccess((recordKey) =>\n succeed({ id: record.envelope.id, key: recordKey })\n )\n )\n )\n ).onSuccess((keyed) => succeed(keyed.find((entry) => entry.key === key)?.id))\n );\n }\n\n /**\n * The body of a persisted record, required to be a string (the store persists\n * only string bodies). Fails loudly rather than blind-casting an `unknown` body\n * into the exact-dedup hash — a non-string existing body is a store-integrity\n * fault, surfaced with context, not a silent miscompute.\n */\n private static _recordBodyString(record: IMemoryRecord<unknown>): Result<string> {\n if (typeof record.body !== 'string') {\n return fail(\n `ingest: stored record '${record.envelope.id}' has a non-string body (got ${typeof record.body})`\n );\n }\n return succeed(record.body);\n }\n\n /** The stage-4 exact-dedup key over `{ kind, body }` (design note §1). */\n private _exactKey(kind: Kind, body: string): Result<string> {\n return this._hasher.computeHash({ kind, body });\n }\n\n /** Stage 5 — relate (host), redirect collapsed targets, validate edges, and run the write-time cycle guard. */\n private async _relate(\n item: IIngestItem,\n writablePlans: ReadonlyArray<ICandidatePlan>,\n redirects: ReadonlyMap<string, IEdgeTarget>,\n scoped: ReadonlyArray<IScopedRecord>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Promise<Result<ReadonlyArray<ICandidateEdge>>> {\n const relationCandidates: IRelationCandidate[] = writablePlans.map((plan) => ({\n candidate: plan.candidate,\n id: plan.refTarget\n }));\n const proposed: Result<ReadonlyArray<ICandidateEdge>> = await this._capture(\n () => this._relationExtractor.relate({ item, candidates: relationCandidates }),\n `ingest '${item.id}': relate`\n );\n if (proposed.isFailure()) {\n return proposed;\n }\n // Redirect BEFORE validation and BEFORE the cycle guard: an edge naming a\n // collapsed candidate must be judged — and persisted — against the record it\n // collapsed into, not against the address that no longer gets written.\n const edges: ReadonlyArray<ICandidateEdge> = MemoryIngestOrchestrator._redirectEdges(\n proposed.value,\n redirects\n );\n // refIds and the existing-record view (`byKey`, shared with the verdict path)\n // both key on the canonical scoped address, so a stem reused across scopes\n // never aliases.\n const refIds: ReadonlySet<string> = new Set<string>(\n writablePlans.map((plan) => edgeTargetKey(plan.refTarget))\n );\n const validation: Result<true> = this._validateEdges(item, edges, refIds, byKey);\n if (validation.isFailure()) {\n return fail(validation.message);\n }\n if (this._cycleGuard === 'reject') {\n const guard: Result<true> = assertNoCycles(\n MemoryIngestOrchestrator._existingEdges(scoped),\n edges.map((e) => ({ source: e.source, target: e.edge.target, type: e.edge.type }))\n );\n if (guard.isFailure()) {\n return fail(`ingest '${item.id}': ${guard.message}`);\n }\n }\n return succeed(edges);\n }\n\n /**\n * The stage-5 edge-target redirect map for this pass: every `duplicate-of`\n * candidate's OWN scoped address, mapped to the address of the record its\n * verdict collapsed it into (design note §3).\n *\n * @remarks\n * A `duplicate-of` verdict means \"this candidate IS that record\". The candidate\n * is therefore not written, and its address never becomes a live reference — so\n * a sibling edge built against it in the same pass would resolve to neither a\n * written candidate nor an existing record and would fail the WHOLE ingest item.\n * That is a second-order hazard of collapsing, not a defect in the edge: the\n * host related two candidates it was correctly told about, and one of them\n * turned out to already exist.\n *\n * Redirecting is the honest repair, and it is independent of {@link DedupScope}\n * — it applies equally to a `'content'` kind, where the collapse is exactly\n * right and the ingest still must not fail.\n *\n * The map cannot chain: {@link MemoryIngestOrchestrator._planFromVerdict}\n * requires every target-bearing verdict's target to already exist in the store\n * snapshot, so a redirect destination is always a persisted record and never\n * another collapsed candidate. One pass is sufficient by construction.\n */\n private static _collapseRedirects(plans: ReadonlyArray<ICandidatePlan>): ReadonlyMap<string, IEdgeTarget> {\n const redirects: Map<string, IEdgeTarget> = new Map<string, IEdgeTarget>();\n for (const plan of plans) {\n if (plan.verdict.verdict === 'duplicate-of') {\n redirects.set(edgeTargetKey(plan.refTarget), plan.verdict.target);\n }\n }\n return redirects;\n }\n\n /**\n * Rewrite each edge whose TARGET names a collapsed candidate to point at the\n * record that candidate collapsed into.\n *\n * @remarks\n * Only the target is redirected. An edge whose SOURCE is a collapsed candidate\n * stays untouched and is still rejected by {@link\n * MemoryIngestOrchestrator._validateEdges}: sources are the records an edge is\n * written ONTO, a collapsed candidate is never written, and the relation\n * extractor is only ever offered writable candidates as edge sources in the\n * first place. Silently relocating such an edge onto an existing record would\n * attribute a link the host never asked for — the loud failure is correct there.\n */\n private static _redirectEdges(\n edges: ReadonlyArray<ICandidateEdge>,\n redirects: ReadonlyMap<string, IEdgeTarget>\n ): ReadonlyArray<ICandidateEdge> {\n if (redirects.size === 0) {\n return edges;\n }\n return edges.map((e) => {\n const to: IEdgeTarget | undefined = redirects.get(edgeTargetKey(e.edge.target));\n return to === undefined ? e : { ...e, edge: { ...e.edge, target: to } };\n });\n }\n\n /**\n * Validate stage-5 edges: each `source` must be a candidate being written; each\n * `target` must resolve to a sibling candidate or an existing store record. All\n * matching is on the canonical scope-qualified address.\n */\n private _validateEdges(\n item: IIngestItem,\n edges: ReadonlyArray<ICandidateEdge>,\n refIds: ReadonlySet<string>,\n byKey: ReadonlyMap<string, IMemoryRecord<unknown>>\n ): Result<true> {\n return mapResults(\n edges.map((edge) => {\n if (!refIds.has(edgeTargetKey(edge.source))) {\n return fail(\n `ingest '${item.id}': edge source '${MemoryIngestOrchestrator._formatTarget(\n edge.source\n )}' is not a candidate being written`\n );\n }\n const targetKey: string = edgeTargetKey(edge.edge.target);\n if (!refIds.has(targetKey) && byKey.get(targetKey) === undefined) {\n return fail(\n `ingest '${item.id}': edge target '${MemoryIngestOrchestrator._formatTarget(\n edge.edge.target\n )}' resolves to neither a sibling candidate nor an existing record`\n );\n }\n return succeed(true);\n })\n ).onSuccess(() => succeed(true));\n }\n\n /** Stage 6 — stamp provenance + edges, admit through the store, record the outcome. */\n private async _loadCandidate(\n item: IIngestItem,\n plan: ICandidatePlan,\n allEdges: ReadonlyArray<ICandidateEdge>\n ): Promise<Result<IIngestedRecordResult>> {\n const refKey: string = edgeTargetKey(plan.refTarget);\n const myEdges: ReadonlyArray<ICandidateEdge> = allEdges.filter((e) => edgeTargetKey(e.source) === refKey);\n if (plan.verdict.verdict === 'duplicate-of') {\n // No write: the existing target satisfied the candidate. The target id is a\n // typed field of the narrowed `duplicate-of` verdict — no cast, no guard.\n return succeed({\n candidate: plan.candidate,\n resolution: plan.verdict,\n disposition: 'deduped',\n id: plan.verdict.target.id,\n edges: myEdges\n });\n }\n return this._buildRecord(item, plan, myEdges).thenOnSuccess(async (record) =>\n (await this._store.put(record))\n .withErrorFormat((msg) => `ingest '${item.id}': write failed: ${msg}`)\n .onSuccess((persisted) => {\n const disposition: IngestDisposition = plan.verdict.verdict === 'merge-into' ? 'merged' : 'written';\n const interlock: 'temporal-versioned' | undefined =\n plan.writeAddress.isVersioned && myEdges.some((e) => e.edge.type === CONTRADICTS_LINK_TYPE)\n ? 'temporal-versioned'\n : undefined;\n return succeed({\n candidate: plan.candidate,\n resolution: plan.verdict,\n disposition,\n id: persisted.envelope.id,\n record: persisted,\n edges: myEdges,\n ...(interlock !== undefined ? { interlock } : {})\n });\n })\n );\n }\n\n /** Build the fully-stamped record to persist (provenance + edges + placeholder txn fields). */\n private _buildRecord(\n item: IIngestItem,\n plan: ICandidatePlan,\n myEdges: ReadonlyArray<ICandidateEdge>\n ): Result<IMemoryRecord<unknown>> {\n const base: Omit<IMemoryEnvelope, 'id' | 'seq' | 'contentHash' | 'created' | 'updated'> =\n plan.candidate.envelope;\n // For merge-into the store's `applyUpdate` REPLACES array fields wholesale, so\n // the persisted envelope must already carry the UNION of the target's existing\n // tags/links/provenance and the candidate's — otherwise the merge silently\n // wipes the target's prior links/tags.\n const target: IMemoryRecord<unknown> | undefined = plan.mergeTarget;\n const priorLinks: ReadonlyArray<IEdge> = target !== undefined ? target.envelope.links : [];\n const priorTags: ReadonlyArray<Tag> = target !== undefined ? target.envelope.tags : [];\n const priorProvenance: IProvenance = target !== undefined ? target.envelope.provenance : { source: '' };\n return Convert.memoryId.convert(plan.writeAddress.idStem).onSuccess((id) =>\n // Dedup the combined links by canonical edge key: the target's prior links, the\n // candidate's own links, and the stage-5 edges (two candidates that resolve\n // merge-into the SAME target share a `refId` — hence the same `myEdges` — and a\n // relation extractor may repeat an edge) each appear exactly once.\n this._dedupEdges([...priorLinks, ...base.links, ...myEdges.map((e) => e.edge)]).onSuccess((links) => {\n const provenance: IProvenance = {\n // Preserve the target's provenance extension keys, overlay the candidate's,\n // then stamp the host-ingest source + derivedFrom (target present only for\n // merge-into; otherwise the seed is inert).\n ...(target !== undefined ? priorProvenance : {}),\n ...base.provenance,\n source: HOST_INGEST_PROVENANCE_SOURCE,\n ...(item.sourceId !== undefined ? { derivedFrom: item.sourceId } : {})\n };\n const envelope: IMemoryEnvelope = {\n ...base,\n id,\n entityId: plan.writeEntityId,\n seq: 0,\n contentHash: '',\n created: 0,\n updated: 0,\n provenance,\n tags: MemoryIngestOrchestrator._unionTags(priorTags, base.tags),\n links\n };\n return succeed({ envelope, body: plan.candidate.body });\n })\n );\n }\n\n /** Union two tag lists, de-duplicated, preserving first-occurrence order. */\n private static _unionTags(prior: ReadonlyArray<Tag>, incoming: ReadonlyArray<Tag>): ReadonlyArray<Tag> {\n const seen: Set<string> = new Set<string>();\n const out: Tag[] = [];\n for (const tag of [...prior, ...incoming]) {\n if (!seen.has(tag)) {\n seen.add(tag);\n out.push(tag);\n }\n }\n return out;\n }\n\n /** De-duplicate a link list by canonical edge hash, preserving first-occurrence order. */\n private _dedupEdges(edges: ReadonlyArray<IEdge>): Result<ReadonlyArray<IEdge>> {\n const seen: Set<string> = new Set<string>();\n const deduped: IEdge[] = [];\n return mapResults(\n edges.map((edge) =>\n this._hasher.computeHash(edge).onSuccess((key) => {\n if (!seen.has(key)) {\n seen.add(key);\n deduped.push(edge);\n }\n return succeed(key);\n })\n )\n ).onSuccess(() => succeed(deduped));\n }\n\n /** Resolve a `(kind, entityId)` to its storage address via the registered codec. */\n private _resolveAddress(entityId: EntityId, kind: Kind): Result<IIdentityCodecResult> {\n const codec: IIdentityCodec | undefined = this._codecs.get(kind) ?? this._defaultCodec;\n if (codec === undefined) {\n return fail(`no identity codec registered for kind '${kind}'`);\n }\n return codec.encode(entityId);\n }\n\n /** Run a host hook, normalizing a thrown/rejected hook into a Failure (never throws across the seam). */\n private async _capture<T>(op: () => Promise<Result<T>>, label: string): Promise<Result<T>> {\n try {\n return await op();\n } catch (err) {\n const message: string = `${label} threw: ${String(err)}`;\n this._logger.warn(message);\n return fail(message);\n }\n }\n\n /**\n * Every existing outbound edge in the snapshot, as cycle-guard edges. The\n * source is the record's own scope-qualified address (already resolved by\n * {@link MemoryIngestOrchestrator._scopeRecords}); the target is the edge's\n * own scoped target. Both ends are scoped so the guard never conflates a stem\n * shared across scopes into one graph node.\n */\n private static _existingEdges(scoped: ReadonlyArray<IScopedRecord>): ReadonlyArray<ICycleGuardEdge> {\n const edges: ICycleGuardEdge[] = [];\n for (const s of scoped) {\n for (const edge of s.record.envelope.links) {\n edges.push({ source: s.address, target: edge.target, type: edge.type });\n }\n }\n return edges;\n }\n\n /**\n * Resolve every snapshot record's scope-qualified `(scope, id)` address via its\n * registered codec. Fails loudly if a record's kind has no resolvable codec —\n * the edge path cannot place an un-scopeable record in the graph, and a missing\n * codec for a stored kind is a real misconfiguration, not something to paper over.\n */\n private _scopeRecords(\n records: ReadonlyArray<IMemoryRecord<unknown>>\n ): Result<ReadonlyArray<IScopedRecord>> {\n return mapResults(\n records.map((record) =>\n this._resolveAddress(record.envelope.entityId, record.envelope.kind)\n .withErrorFormat((msg) => `cannot resolve scope for stored record '${record.envelope.id}': ${msg}`)\n .onSuccess((addr) => succeed({ address: { scope: addr.scope, id: record.envelope.id }, record }))\n )\n );\n }\n\n /** Human-readable `scope/id` rendering of a scoped target for edge-validation diagnostics. */\n private static _formatTarget(target: IEdgeTarget): string {\n return `${target.scope}/${target.id}`;\n }\n\n /** A provisional record for embedding a candidate (placeholder txn-time fields). */\n private static _provisionalRecord(\n candidate: ICandidateRecord,\n idStem: string,\n body: string\n ): Result<IMemoryRecord<unknown>> {\n return Convert.memoryId.convert(idStem).onSuccess((id) => {\n const envelope: IMemoryEnvelope = {\n ...candidate.envelope,\n id,\n seq: 0,\n contentHash: '',\n created: 0,\n updated: 0\n };\n return succeed({ envelope, body });\n });\n }\n\n /** Require a candidate body to be a string (the store persists only string bodies). */\n private static _asStringBody(item: IIngestItem, candidate: ICandidateRecord): Result<string> {\n if (typeof candidate.body !== 'string') {\n return fail(\n `ingest '${item.id}': candidate body for kind '${\n candidate.envelope.kind\n }' must be a string (got ${typeof candidate.body})`\n );\n }\n return succeed(candidate.body);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"memoryObservationStore.d.ts","sourceRoot":"","sources":["../../../src/packlets/observe/memoryObservationStore.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,MAAM,EAAiB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhG;;;GAGG;AACH,MAAM,WAAW,mCAAmC;IAClD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAC5D;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4D;IAEpF;;;OAGG;IACH,OAAO;IAIP;;;;;OAKG;IACH,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;;;OAKG;WACW,MAAM,CAAC,MAAM,CAAC,EAAE,mCAAmC,GAAG,MAAM,CAAC,sBAAsB,CAAC;IAYlG;;OAEG;IACI,OAAO,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAK1E;;;;OAIG;IACI,KAAK,CAAC,QAAQ,CAAC,EAAE,uBAAuB,GAAG,aAAa,CAAC,wBAAwB,CAAC;IASzF;;;;OAIG;IACI,KAAK,IAAI,IAAI;IAIpB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;CAqBxB"}
1
+ {"version":3,"file":"memoryObservationStore.d.ts","sourceRoot":"","sources":["../../../src/packlets/observe/memoryObservationStore.ts"],"names":[],"mappings":"AAKA,OAAO,EAAe,MAAM,EAAiB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEhG;;;GAGG;AACH,MAAM,WAAW,mCAAmC;IAClD;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAC5D;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4D;IAEpF;;;OAGG;IACH,OAAO;IAIP;;;;;OAKG;IACH,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;;;OAKG;WACW,MAAM,CAAC,MAAM,CAAC,EAAE,mCAAmC,GAAG,MAAM,CAAC,sBAAsB,CAAC;IAYlG;;OAEG;IACI,OAAO,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAK1E;;;;OAIG;IACI,KAAK,CAAC,QAAQ,CAAC,EAAE,uBAAuB,GAAG,aAAa,CAAC,wBAAwB,CAAC;IASzF;;;;OAIG;IACI,KAAK,IAAI,IAAI;IAIpB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;CA2BxB"}