@atomicmemory/core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (589) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +201 -0
  3. package/README.md +314 -0
  4. package/dist/app/bind-ephemeral.d.ts +18 -0
  5. package/dist/app/bind-ephemeral.js +22 -0
  6. package/dist/app/cors-headers.d.ts +12 -0
  7. package/dist/app/cors-headers.js +18 -0
  8. package/dist/app/create-app.d.ts +25 -0
  9. package/dist/app/create-app.js +156 -0
  10. package/dist/app/runtime-config-route-snapshot.d.ts +27 -0
  11. package/dist/app/runtime-config-route-snapshot.js +27 -0
  12. package/dist/app/runtime-container.d.ts +281 -0
  13. package/dist/app/runtime-container.js +297 -0
  14. package/dist/app/startup-checks.d.ts +28 -0
  15. package/dist/app/startup-checks.js +45 -0
  16. package/dist/bin.d.ts +17 -0
  17. package/dist/bin.js +128 -0
  18. package/dist/config.d.ts +680 -0
  19. package/dist/config.js +808 -0
  20. package/dist/db/agent-trust-repository.d.ts +49 -0
  21. package/dist/db/agent-trust-repository.js +66 -0
  22. package/dist/db/belief-edges-repository.d.ts +68 -0
  23. package/dist/db/belief-edges-repository.js +124 -0
  24. package/dist/db/claim-repository.d.ts +6 -0
  25. package/dist/db/claim-repository.js +4 -0
  26. package/dist/db/contradictions-repository.d.ts +56 -0
  27. package/dist/db/contradictions-repository.js +88 -0
  28. package/dist/db/document-chunk-repository.d.ts +48 -0
  29. package/dist/db/document-chunk-repository.js +145 -0
  30. package/dist/db/document-chunk-types.d.ts +35 -0
  31. package/dist/db/document-chunk-types.js +9 -0
  32. package/dist/db/document-list-cursor.d.ts +45 -0
  33. package/dist/db/document-list-cursor.js +111 -0
  34. package/dist/db/document-list-repository.d.ts +103 -0
  35. package/dist/db/document-list-repository.js +204 -0
  36. package/dist/db/entity-cards-repository.d.ts +37 -0
  37. package/dist/db/entity-cards-repository.js +46 -0
  38. package/dist/db/entity-values-repository.d.ts +26 -0
  39. package/dist/db/entity-values-repository.js +57 -0
  40. package/dist/db/link-repository.d.ts +30 -0
  41. package/dist/db/link-repository.js +54 -0
  42. package/dist/db/memory-repository.d.ts +163 -0
  43. package/dist/db/memory-repository.js +232 -0
  44. package/dist/db/migrate.d.ts +6 -0
  45. package/dist/db/migrate.js +36 -0
  46. package/dist/db/mmr.d.ts +14 -0
  47. package/dist/db/mmr.js +57 -0
  48. package/dist/db/passport-feed-repository.d.ts +91 -0
  49. package/dist/db/passport-feed-repository.js +198 -0
  50. package/dist/db/pg-episode-store.d.ts +19 -0
  51. package/dist/db/pg-episode-store.js +17 -0
  52. package/dist/db/pg-link-store.d.ts +17 -0
  53. package/dist/db/pg-link-store.js +14 -0
  54. package/dist/db/pg-memory-store.d.ts +68 -0
  55. package/dist/db/pg-memory-store.js +53 -0
  56. package/dist/db/pg-recap-store.d.ts +13 -0
  57. package/dist/db/pg-recap-store.js +19 -0
  58. package/dist/db/pg-representation-store.d.ts +17 -0
  59. package/dist/db/pg-representation-store.js +17 -0
  60. package/dist/db/pg-search-store.d.ts +29 -0
  61. package/dist/db/pg-search-store.js +47 -0
  62. package/dist/db/pool.d.ts +5 -0
  63. package/dist/db/pool.js +21 -0
  64. package/dist/db/ppr.d.ts +56 -0
  65. package/dist/db/ppr.js +178 -0
  66. package/dist/db/query-helpers.d.ts +44 -0
  67. package/dist/db/query-helpers.js +60 -0
  68. package/dist/db/raw-doc-artifact-sync.d.ts +128 -0
  69. package/dist/db/raw-doc-artifact-sync.js +259 -0
  70. package/dist/db/raw-document-blob-repository.d.ts +148 -0
  71. package/dist/db/raw-document-blob-repository.js +300 -0
  72. package/dist/db/raw-document-repository.d.ts +104 -0
  73. package/dist/db/raw-document-repository.js +410 -0
  74. package/dist/db/raw-document-status-repository.d.ts +122 -0
  75. package/dist/db/raw-document-status-repository.js +183 -0
  76. package/dist/db/raw-document-types.d.ts +236 -0
  77. package/dist/db/raw-document-types.js +10 -0
  78. package/dist/db/raw-storage-reconciliation-repository.d.ts +110 -0
  79. package/dist/db/raw-storage-reconciliation-repository.js +200 -0
  80. package/dist/db/reflection-jobs-repository.d.ts +33 -0
  81. package/dist/db/reflection-jobs-repository.js +48 -0
  82. package/dist/db/reflections-repository.d.ts +41 -0
  83. package/dist/db/reflections-repository.js +83 -0
  84. package/dist/db/repository-claims.d.ts +141 -0
  85. package/dist/db/repository-claims.js +376 -0
  86. package/dist/db/repository-deferred-audn.d.ts +33 -0
  87. package/dist/db/repository-deferred-audn.js +69 -0
  88. package/dist/db/repository-document-delete.d.ts +53 -0
  89. package/dist/db/repository-document-delete.js +156 -0
  90. package/dist/db/repository-entities.d.ts +114 -0
  91. package/dist/db/repository-entities.js +317 -0
  92. package/dist/db/repository-entity-attributes.d.ts +41 -0
  93. package/dist/db/repository-entity-attributes.js +65 -0
  94. package/dist/db/repository-entity-graph.d.ts +32 -0
  95. package/dist/db/repository-entity-graph.js +87 -0
  96. package/dist/db/repository-first-mentions.d.ts +41 -0
  97. package/dist/db/repository-first-mentions.js +79 -0
  98. package/dist/db/repository-lessons.d.ts +51 -0
  99. package/dist/db/repository-lessons.js +90 -0
  100. package/dist/db/repository-links.d.ts +26 -0
  101. package/dist/db/repository-links.js +105 -0
  102. package/dist/db/repository-observation.d.ts +26 -0
  103. package/dist/db/repository-observation.js +51 -0
  104. package/dist/db/repository-read.d.ts +56 -0
  105. package/dist/db/repository-read.js +271 -0
  106. package/dist/db/repository-recaps.d.ts +59 -0
  107. package/dist/db/repository-recaps.js +158 -0
  108. package/dist/db/repository-representations.d.ts +48 -0
  109. package/dist/db/repository-representations.js +162 -0
  110. package/dist/db/repository-temporal-state.d.ts +35 -0
  111. package/dist/db/repository-temporal-state.js +46 -0
  112. package/dist/db/repository-tll.d.ts +88 -0
  113. package/dist/db/repository-tll.js +179 -0
  114. package/dist/db/repository-types.d.ts +313 -0
  115. package/dist/db/repository-types.js +142 -0
  116. package/dist/db/repository-user-profiles.d.ts +17 -0
  117. package/dist/db/repository-user-profiles.js +28 -0
  118. package/dist/db/repository-vector-search.d.ts +33 -0
  119. package/dist/db/repository-vector-search.js +373 -0
  120. package/dist/db/repository-wipe.d.ts +34 -0
  121. package/dist/db/repository-wipe.js +94 -0
  122. package/dist/db/repository-write.d.ts +61 -0
  123. package/dist/db/repository-write.js +279 -0
  124. package/dist/db/schema.sql +1355 -0
  125. package/dist/db/storage-artifact-delete-tx.d.ts +56 -0
  126. package/dist/db/storage-artifact-delete-tx.js +123 -0
  127. package/dist/db/storage-artifact-providers.d.ts +21 -0
  128. package/dist/db/storage-artifact-providers.js +21 -0
  129. package/dist/db/storage-artifact-recovery-repository.d.ts +66 -0
  130. package/dist/db/storage-artifact-recovery-repository.js +58 -0
  131. package/dist/db/storage-artifact-repository.d.ts +329 -0
  132. package/dist/db/storage-artifact-repository.js +497 -0
  133. package/dist/db/stores.d.ts +220 -0
  134. package/dist/db/stores.js +12 -0
  135. package/dist/db/summaries-repository.d.ts +74 -0
  136. package/dist/db/summaries-repository.js +125 -0
  137. package/dist/eval/beam-10m-loader.d.ts +98 -0
  138. package/dist/eval/beam-10m-loader.js +128 -0
  139. package/dist/index.d.ts +18 -0
  140. package/dist/index.js +17 -0
  141. package/dist/middleware/require-bearer.d.ts +27 -0
  142. package/dist/middleware/require-bearer.js +60 -0
  143. package/dist/middleware/validate-response.d.ts +33 -0
  144. package/dist/middleware/validate-response.js +55 -0
  145. package/dist/middleware/validate.d.ts +43 -0
  146. package/dist/middleware/validate.js +85 -0
  147. package/dist/routes/agents.d.ts +13 -0
  148. package/dist/routes/agents.js +89 -0
  149. package/dist/routes/document-response-formatters.d.ts +98 -0
  150. package/dist/routes/document-response-formatters.js +243 -0
  151. package/dist/routes/documents.d.ts +74 -0
  152. package/dist/routes/documents.js +425 -0
  153. package/dist/routes/memories.d.ts +29 -0
  154. package/dist/routes/memories.js +725 -0
  155. package/dist/routes/memory-response-formatters.d.ts +179 -0
  156. package/dist/routes/memory-response-formatters.js +210 -0
  157. package/dist/routes/public-raw-storage-metadata.d.ts +54 -0
  158. package/dist/routes/public-raw-storage-metadata.js +56 -0
  159. package/dist/routes/reflect.d.ts +14 -0
  160. package/dist/routes/reflect.js +19 -0
  161. package/dist/routes/response-schema-map.d.ts +14 -0
  162. package/dist/routes/response-schema-map.js +69 -0
  163. package/dist/routes/route-errors.d.ts +12 -0
  164. package/dist/routes/route-errors.js +30 -0
  165. package/dist/routes/storage-error-handlers.d.ts +34 -0
  166. package/dist/routes/storage-error-handlers.js +185 -0
  167. package/dist/routes/storage-response-formatters.d.ts +44 -0
  168. package/dist/routes/storage-response-formatters.js +155 -0
  169. package/dist/routes/storage.d.ts +38 -0
  170. package/dist/routes/storage.js +369 -0
  171. package/dist/routes/upstream-provider-errors.d.ts +19 -0
  172. package/dist/routes/upstream-provider-errors.js +95 -0
  173. package/dist/schemas/agents.d.ts +79 -0
  174. package/dist/schemas/agents.js +126 -0
  175. package/dist/schemas/common.d.ts +110 -0
  176. package/dist/schemas/common.js +190 -0
  177. package/dist/schemas/document-list-responses.d.ts +102 -0
  178. package/dist/schemas/document-list-responses.js +87 -0
  179. package/dist/schemas/document-list-schemas.d.ts +123 -0
  180. package/dist/schemas/document-list-schemas.js +174 -0
  181. package/dist/schemas/document-response-schemas.d.ts +610 -0
  182. package/dist/schemas/document-response-schemas.js +264 -0
  183. package/dist/schemas/document-status-envelope.d.ts +48 -0
  184. package/dist/schemas/document-status-envelope.js +54 -0
  185. package/dist/schemas/documents.d.ts +292 -0
  186. package/dist/schemas/documents.js +449 -0
  187. package/dist/schemas/errors.d.ts +75 -0
  188. package/dist/schemas/errors.js +105 -0
  189. package/dist/schemas/memories.d.ts +378 -0
  190. package/dist/schemas/memories.js +542 -0
  191. package/dist/schemas/openapi.d.ts +24 -0
  192. package/dist/schemas/openapi.js +1038 -0
  193. package/dist/schemas/response-scalars.d.ts +10 -0
  194. package/dist/schemas/response-scalars.js +10 -0
  195. package/dist/schemas/responses.d.ts +536 -0
  196. package/dist/schemas/responses.js +350 -0
  197. package/dist/schemas/search-response-parts.d.ts +97 -0
  198. package/dist/schemas/search-response-parts.js +103 -0
  199. package/dist/schemas/storage-schemas.d.ts +175 -0
  200. package/dist/schemas/storage-schemas.js +277 -0
  201. package/dist/schemas/zod-setup.d.ts +15 -0
  202. package/dist/schemas/zod-setup.js +17 -0
  203. package/dist/server.d.ts +13 -0
  204. package/dist/server.js +57 -0
  205. package/dist/services/abstract-query-policy.d.ts +13 -0
  206. package/dist/services/abstract-query-policy.js +50 -0
  207. package/dist/services/affinity-clustering.d.ts +66 -0
  208. package/dist/services/affinity-clustering.js +125 -0
  209. package/dist/services/agentic-retrieval.d.ts +38 -0
  210. package/dist/services/agentic-retrieval.js +126 -0
  211. package/dist/services/answer-format.d.ts +56 -0
  212. package/dist/services/answer-format.js +118 -0
  213. package/dist/services/answer-rescue.d.ts +72 -0
  214. package/dist/services/answer-rescue.js +177 -0
  215. package/dist/services/answer-verifier.d.ts +24 -0
  216. package/dist/services/answer-verifier.js +73 -0
  217. package/dist/services/api-retry.d.ts +6 -0
  218. package/dist/services/api-retry.js +41 -0
  219. package/dist/services/assistant-turn-filter.d.ts +20 -0
  220. package/dist/services/assistant-turn-filter.js +69 -0
  221. package/dist/services/atomicmem-uri.d.ts +33 -0
  222. package/dist/services/atomicmem-uri.js +86 -0
  223. package/dist/services/audit-events.d.ts +54 -0
  224. package/dist/services/audit-events.js +56 -0
  225. package/dist/services/chunked-extraction.d.ts +21 -0
  226. package/dist/services/chunked-extraction.js +108 -0
  227. package/dist/services/claim-slotting.d.ts +27 -0
  228. package/dist/services/claim-slotting.js +38 -0
  229. package/dist/services/claude-code-llm.d.ts +19 -0
  230. package/dist/services/claude-code-llm.js +96 -0
  231. package/dist/services/composite-dedup.d.ts +50 -0
  232. package/dist/services/composite-dedup.js +153 -0
  233. package/dist/services/composite-grouping.d.ts +41 -0
  234. package/dist/services/composite-grouping.js +111 -0
  235. package/dist/services/composite-staleness.d.ts +20 -0
  236. package/dist/services/composite-staleness.js +50 -0
  237. package/dist/services/conciseness-preference.d.ts +14 -0
  238. package/dist/services/conciseness-preference.js +42 -0
  239. package/dist/services/conflict-policy.d.ts +20 -0
  240. package/dist/services/conflict-policy.js +335 -0
  241. package/dist/services/consensus-extraction.d.ts +39 -0
  242. package/dist/services/consensus-extraction.js +147 -0
  243. package/dist/services/consensus-validation.d.ts +52 -0
  244. package/dist/services/consensus-validation.js +206 -0
  245. package/dist/services/consolidation-service.d.ts +60 -0
  246. package/dist/services/consolidation-service.js +171 -0
  247. package/dist/services/content-detection.d.ts +18 -0
  248. package/dist/services/content-detection.js +25 -0
  249. package/dist/services/contradiction-surfacing.d.ts +62 -0
  250. package/dist/services/contradiction-surfacing.js +111 -0
  251. package/dist/services/cost-telemetry.d.ts +39 -0
  252. package/dist/services/cost-telemetry.js +58 -0
  253. package/dist/services/counter-evidence.d.ts +34 -0
  254. package/dist/services/counter-evidence.js +92 -0
  255. package/dist/services/current-state-ranking.d.ts +21 -0
  256. package/dist/services/current-state-ranking.js +152 -0
  257. package/dist/services/deferred-audn.d.ts +47 -0
  258. package/dist/services/deferred-audn.js +162 -0
  259. package/dist/services/document-chunker.d.ts +50 -0
  260. package/dist/services/document-chunker.js +153 -0
  261. package/dist/services/document-failure-markers.d.ts +91 -0
  262. package/dist/services/document-failure-markers.js +305 -0
  263. package/dist/services/document-indexer.d.ts +122 -0
  264. package/dist/services/document-indexer.js +405 -0
  265. package/dist/services/document-service.d.ts +245 -0
  266. package/dist/services/document-service.js +325 -0
  267. package/dist/services/document-upload-artifact-sync.d.ts +80 -0
  268. package/dist/services/document-upload-artifact-sync.js +162 -0
  269. package/dist/services/document-upload-beta2-recovery.d.ts +72 -0
  270. package/dist/services/document-upload-beta2-recovery.js +94 -0
  271. package/dist/services/document-upload.d.ts +44 -0
  272. package/dist/services/document-upload.js +353 -0
  273. package/dist/services/embedding.d.ts +57 -0
  274. package/dist/services/embedding.js +416 -0
  275. package/dist/services/entity-attribute-extractor.d.ts +34 -0
  276. package/dist/services/entity-attribute-extractor.js +117 -0
  277. package/dist/services/entity-card-synthesis.d.ts +54 -0
  278. package/dist/services/entity-card-synthesis.js +92 -0
  279. package/dist/services/entity-dedup.d.ts +9 -0
  280. package/dist/services/entity-dedup.js +14 -0
  281. package/dist/services/entity-graph.d.ts +17 -0
  282. package/dist/services/entity-graph.js +135 -0
  283. package/dist/services/entropy-gate.d.ts +52 -0
  284. package/dist/services/entropy-gate.js +56 -0
  285. package/dist/services/episode-fetcher.d.ts +47 -0
  286. package/dist/services/episode-fetcher.js +128 -0
  287. package/dist/services/event-anchor-facts.d.ts +8 -0
  288. package/dist/services/event-anchor-facts.js +205 -0
  289. package/dist/services/event-chain-detector.d.ts +52 -0
  290. package/dist/services/event-chain-detector.js +83 -0
  291. package/dist/services/extraction-cache.d.ts +9 -0
  292. package/dist/services/extraction-cache.js +54 -0
  293. package/dist/services/extraction-enrichment.d.ts +9 -0
  294. package/dist/services/extraction-enrichment.js +223 -0
  295. package/dist/services/extraction.d.ts +69 -0
  296. package/dist/services/extraction.js +596 -0
  297. package/dist/services/fact-normalization.d.ts +12 -0
  298. package/dist/services/fact-normalization.js +248 -0
  299. package/dist/services/filecoin-observability.d.ts +127 -0
  300. package/dist/services/filecoin-observability.js +200 -0
  301. package/dist/services/first-mention-service.d.ts +76 -0
  302. package/dist/services/first-mention-service.js +186 -0
  303. package/dist/services/hierarchical-retrieval.d.ts +49 -0
  304. package/dist/services/hierarchical-retrieval.js +50 -0
  305. package/dist/services/ingest-fact-pipeline.d.ts +32 -0
  306. package/dist/services/ingest-fact-pipeline.js +212 -0
  307. package/dist/services/ingest-post-write.d.ts +50 -0
  308. package/dist/services/ingest-post-write.js +117 -0
  309. package/dist/services/ingest-trace.d.ts +32 -0
  310. package/dist/services/ingest-trace.js +60 -0
  311. package/dist/services/input-sanitizer.d.ts +41 -0
  312. package/dist/services/input-sanitizer.js +135 -0
  313. package/dist/services/iterative-retrieval.d.ts +26 -0
  314. package/dist/services/iterative-retrieval.js +139 -0
  315. package/dist/services/keyword-expansion.d.ts +10 -0
  316. package/dist/services/keyword-expansion.js +26 -0
  317. package/dist/services/lesson-service.d.ts +68 -0
  318. package/dist/services/lesson-service.js +178 -0
  319. package/dist/services/literal-extractor.d.ts +16 -0
  320. package/dist/services/literal-extractor.js +74 -0
  321. package/dist/services/literal-list-protection.d.ts +17 -0
  322. package/dist/services/literal-list-protection.js +134 -0
  323. package/dist/services/literal-query-expansion.d.ts +20 -0
  324. package/dist/services/literal-query-expansion.js +181 -0
  325. package/dist/services/llm.d.ts +61 -0
  326. package/dist/services/llm.js +265 -0
  327. package/dist/services/memcell-projection.d.ts +17 -0
  328. package/dist/services/memcell-projection.js +41 -0
  329. package/dist/services/memory-audn.d.ts +43 -0
  330. package/dist/services/memory-audn.js +419 -0
  331. package/dist/services/memory-crud.d.ts +93 -0
  332. package/dist/services/memory-crud.js +255 -0
  333. package/dist/services/memory-ingest.d.ts +21 -0
  334. package/dist/services/memory-ingest.js +249 -0
  335. package/dist/services/memory-lifecycle.d.ts +75 -0
  336. package/dist/services/memory-lifecycle.js +108 -0
  337. package/dist/services/memory-lineage.d.ts +181 -0
  338. package/dist/services/memory-lineage.js +232 -0
  339. package/dist/services/memory-network.d.ts +40 -0
  340. package/dist/services/memory-network.js +75 -0
  341. package/dist/services/memory-search-types.d.ts +25 -0
  342. package/dist/services/memory-search-types.js +10 -0
  343. package/dist/services/memory-search.d.ts +48 -0
  344. package/dist/services/memory-search.js +505 -0
  345. package/dist/services/memory-service-types.d.ts +371 -0
  346. package/dist/services/memory-service-types.js +8 -0
  347. package/dist/services/memory-service.d.ts +152 -0
  348. package/dist/services/memory-service.js +225 -0
  349. package/dist/services/memory-storage.d.ts +33 -0
  350. package/dist/services/memory-storage.js +328 -0
  351. package/dist/services/msr-aggregator.d.ts +38 -0
  352. package/dist/services/msr-aggregator.js +97 -0
  353. package/dist/services/msr-detector.d.ts +35 -0
  354. package/dist/services/msr-detector.js +65 -0
  355. package/dist/services/namespace-retrieval.d.ts +60 -0
  356. package/dist/services/namespace-retrieval.js +180 -0
  357. package/dist/services/observation-date-extraction.d.ts +12 -0
  358. package/dist/services/observation-date-extraction.js +50 -0
  359. package/dist/services/observation-service.d.ts +27 -0
  360. package/dist/services/observation-service.js +84 -0
  361. package/dist/services/packaging-observability.d.ts +29 -0
  362. package/dist/services/packaging-observability.js +146 -0
  363. package/dist/services/query-expansion.d.ts +83 -0
  364. package/dist/services/query-expansion.js +242 -0
  365. package/dist/services/query-keyword-matches.d.ts +6 -0
  366. package/dist/services/query-keyword-matches.js +56 -0
  367. package/dist/services/query-term-visibility.d.ts +28 -0
  368. package/dist/services/query-term-visibility.js +100 -0
  369. package/dist/services/quick-extraction.d.ts +25 -0
  370. package/dist/services/quick-extraction.js +431 -0
  371. package/dist/services/quoted-entity-extraction.d.ts +10 -0
  372. package/dist/services/quoted-entity-extraction.js +161 -0
  373. package/dist/services/raw-storage-reconciler-backoff.d.ts +8 -0
  374. package/dist/services/raw-storage-reconciler-backoff.js +14 -0
  375. package/dist/services/raw-storage-reconciler-scheduler.d.ts +29 -0
  376. package/dist/services/raw-storage-reconciler-scheduler.js +43 -0
  377. package/dist/services/raw-storage-reconciler.d.ts +71 -0
  378. package/dist/services/raw-storage-reconciler.js +278 -0
  379. package/dist/services/recap-builder.d.ts +49 -0
  380. package/dist/services/recap-builder.js +157 -0
  381. package/dist/services/reflect-jobs.d.ts +23 -0
  382. package/dist/services/reflect-jobs.js +36 -0
  383. package/dist/services/reflect-prompts.d.ts +71 -0
  384. package/dist/services/reflect-prompts.js +99 -0
  385. package/dist/services/reflect-retrieval.d.ts +33 -0
  386. package/dist/services/reflect-retrieval.js +30 -0
  387. package/dist/services/reflect.d.ts +49 -0
  388. package/dist/services/reflect.js +84 -0
  389. package/dist/services/relative-temporal.d.ts +14 -0
  390. package/dist/services/relative-temporal.js +163 -0
  391. package/dist/services/relevance-policy.d.ts +37 -0
  392. package/dist/services/relevance-policy.js +109 -0
  393. package/dist/services/rerank.d.ts +32 -0
  394. package/dist/services/rerank.js +118 -0
  395. package/dist/services/reranker.d.ts +20 -0
  396. package/dist/services/reranker.js +99 -0
  397. package/dist/services/retrieval-channel-rules.d.ts +34 -0
  398. package/dist/services/retrieval-channel-rules.js +41 -0
  399. package/dist/services/retrieval-config-overlay.d.ts +36 -0
  400. package/dist/services/retrieval-config-overlay.js +44 -0
  401. package/dist/services/retrieval-format.d.ts +119 -0
  402. package/dist/services/retrieval-format.js +559 -0
  403. package/dist/services/retrieval-policy.d.ts +69 -0
  404. package/dist/services/retrieval-policy.js +275 -0
  405. package/dist/services/retrieval-profiles.d.ts +37 -0
  406. package/dist/services/retrieval-profiles.js +90 -0
  407. package/dist/services/retrieval-side-effects.d.ts +14 -0
  408. package/dist/services/retrieval-side-effects.js +26 -0
  409. package/dist/services/retrieval-trace.d.ts +108 -0
  410. package/dist/services/retrieval-trace.js +147 -0
  411. package/dist/services/rrf-fusion.d.ts +18 -0
  412. package/dist/services/rrf-fusion.js +34 -0
  413. package/dist/services/search-pipeline.d.ts +71 -0
  414. package/dist/services/search-pipeline.js +788 -0
  415. package/dist/services/session-date.d.ts +20 -0
  416. package/dist/services/session-date.js +61 -0
  417. package/dist/services/session-packaging.d.ts +53 -0
  418. package/dist/services/session-packaging.js +182 -0
  419. package/dist/services/session-summary-generator.d.ts +53 -0
  420. package/dist/services/session-summary-generator.js +134 -0
  421. package/dist/services/specialists/cr-specialist.d.ts +52 -0
  422. package/dist/services/specialists/cr-specialist.js +121 -0
  423. package/dist/services/specialists/dispatch.d.ts +53 -0
  424. package/dist/services/specialists/dispatch.js +102 -0
  425. package/dist/services/specialists/ie-ku-specialist.d.ts +37 -0
  426. package/dist/services/specialists/ie-ku-specialist.js +63 -0
  427. package/dist/services/specialists/msr-specialist.d.ts +61 -0
  428. package/dist/services/specialists/msr-specialist.js +162 -0
  429. package/dist/services/specialists/tr-specialist.d.ts +37 -0
  430. package/dist/services/specialists/tr-specialist.js +146 -0
  431. package/dist/services/storage-key-prefix.d.ts +42 -0
  432. package/dist/services/storage-key-prefix.js +45 -0
  433. package/dist/services/storage-put-recovery.d.ts +71 -0
  434. package/dist/services/storage-put-recovery.js +269 -0
  435. package/dist/services/storage-service-errors.d.ts +124 -0
  436. package/dist/services/storage-service-errors.js +189 -0
  437. package/dist/services/storage-service.d.ts +176 -0
  438. package/dist/services/storage-service.js +423 -0
  439. package/dist/services/subject-aware-ranking.d.ts +19 -0
  440. package/dist/services/subject-aware-ranking.js +161 -0
  441. package/dist/services/supplemental-extraction.d.ts +7 -0
  442. package/dist/services/supplemental-extraction.js +116 -0
  443. package/dist/services/tbc-execution.d.ts +49 -0
  444. package/dist/services/tbc-execution.js +284 -0
  445. package/dist/services/temporal-classifier.d.ts +56 -0
  446. package/dist/services/temporal-classifier.js +94 -0
  447. package/dist/services/temporal-endpoint-evidence.d.ts +12 -0
  448. package/dist/services/temporal-endpoint-evidence.js +313 -0
  449. package/dist/services/temporal-fingerprint.d.ts +6 -0
  450. package/dist/services/temporal-fingerprint.js +12 -0
  451. package/dist/services/temporal-format.d.ts +9 -0
  452. package/dist/services/temporal-format.js +21 -0
  453. package/dist/services/temporal-intent.d.ts +39 -0
  454. package/dist/services/temporal-intent.js +78 -0
  455. package/dist/services/temporal-query-constraints.d.ts +16 -0
  456. package/dist/services/temporal-query-constraints.js +107 -0
  457. package/dist/services/temporal-query-expansion.d.ts +14 -0
  458. package/dist/services/temporal-query-expansion.js +131 -0
  459. package/dist/services/temporal-rerank.d.ts +22 -0
  460. package/dist/services/temporal-rerank.js +47 -0
  461. package/dist/services/temporal-result-protection.d.ts +7 -0
  462. package/dist/services/temporal-result-protection.js +60 -0
  463. package/dist/services/temporal-state-write.d.ts +57 -0
  464. package/dist/services/temporal-state-write.js +45 -0
  465. package/dist/services/tiered-context.d.ts +87 -0
  466. package/dist/services/tiered-context.js +214 -0
  467. package/dist/services/tiered-loading.d.ts +88 -0
  468. package/dist/services/tiered-loading.js +263 -0
  469. package/dist/services/timeline-pack.d.ts +36 -0
  470. package/dist/services/timeline-pack.js +50 -0
  471. package/dist/services/timing.d.ts +13 -0
  472. package/dist/services/timing.js +72 -0
  473. package/dist/services/tll-augmentation.d.ts +20 -0
  474. package/dist/services/tll-augmentation.js +125 -0
  475. package/dist/services/tll-retrieval.d.ts +55 -0
  476. package/dist/services/tll-retrieval.js +101 -0
  477. package/dist/services/topic-abstraction.d.ts +36 -0
  478. package/dist/services/topic-abstraction.js +105 -0
  479. package/dist/services/trust-scoring.d.ts +43 -0
  480. package/dist/services/trust-scoring.js +89 -0
  481. package/dist/services/typed-belief-calculus.d.ts +126 -0
  482. package/dist/services/typed-belief-calculus.js +204 -0
  483. package/dist/services/upload-config.d.ts +34 -0
  484. package/dist/services/upload-config.js +23 -0
  485. package/dist/services/upload-decision.d.ts +65 -0
  486. package/dist/services/upload-decision.js +98 -0
  487. package/dist/services/upload-helpers.d.ts +107 -0
  488. package/dist/services/upload-helpers.js +148 -0
  489. package/dist/services/user-profile-builder.d.ts +22 -0
  490. package/dist/services/user-profile-builder.js +109 -0
  491. package/dist/services/voyage-embedding.d.ts +22 -0
  492. package/dist/services/voyage-embedding.js +77 -0
  493. package/dist/services/write-security.d.ts +31 -0
  494. package/dist/services/write-security.js +64 -0
  495. package/dist/storage/artifact-public-redaction.d.ts +34 -0
  496. package/dist/storage/artifact-public-redaction.js +83 -0
  497. package/dist/storage/cleanup.d.ts +103 -0
  498. package/dist/storage/cleanup.js +138 -0
  499. package/dist/storage/codec-factory.d.ts +17 -0
  500. package/dist/storage/codec-factory.js +33 -0
  501. package/dist/storage/codecs/aes-gcm-codec.d.ts +44 -0
  502. package/dist/storage/codecs/aes-gcm-codec.js +108 -0
  503. package/dist/storage/codecs/noop-codec.d.ts +16 -0
  504. package/dist/storage/codecs/noop-codec.js +23 -0
  505. package/dist/storage/factory.d.ts +44 -0
  506. package/dist/storage/factory.js +99 -0
  507. package/dist/storage/filecoin-cid-validation.d.ts +82 -0
  508. package/dist/storage/filecoin-cid-validation.js +122 -0
  509. package/dist/storage/filecoin-public-metadata.d.ts +73 -0
  510. package/dist/storage/filecoin-public-metadata.js +110 -0
  511. package/dist/storage/local-fs-store.d.ts +39 -0
  512. package/dist/storage/local-fs-store.js +145 -0
  513. package/dist/storage/pointer-uri-allowlist.d.ts +38 -0
  514. package/dist/storage/pointer-uri-allowlist.js +70 -0
  515. package/dist/storage/provider-metadata-projection.d.ts +27 -0
  516. package/dist/storage/provider-metadata-projection.js +68 -0
  517. package/dist/storage/providers/filecoin/backend.d.ts +42 -0
  518. package/dist/storage/providers/filecoin/backend.js +250 -0
  519. package/dist/storage/providers/filecoin/config.d.ts +70 -0
  520. package/dist/storage/providers/filecoin/config.js +275 -0
  521. package/dist/storage/providers/filecoin/errors.d.ts +45 -0
  522. package/dist/storage/providers/filecoin/errors.js +56 -0
  523. package/dist/storage/providers/filecoin/filecoin-pin-car.d.ts +78 -0
  524. package/dist/storage/providers/filecoin/filecoin-pin-car.js +155 -0
  525. package/dist/storage/providers/filecoin/filecoin-pin-client.d.ts +92 -0
  526. package/dist/storage/providers/filecoin/filecoin-pin-client.js +199 -0
  527. package/dist/storage/providers/filecoin/filecoin-pin-mapping.d.ts +58 -0
  528. package/dist/storage/providers/filecoin/filecoin-pin-mapping.js +103 -0
  529. package/dist/storage/providers/filecoin/filecoin-pin-timeout.d.ts +30 -0
  530. package/dist/storage/providers/filecoin/filecoin-pin-timeout.js +53 -0
  531. package/dist/storage/providers/filecoin/filecoin-pin-vendor.d.ts +111 -0
  532. package/dist/storage/providers/filecoin/filecoin-pin-vendor.js +87 -0
  533. package/dist/storage/providers/filecoin/hints.d.ts +71 -0
  534. package/dist/storage/providers/filecoin/hints.js +123 -0
  535. package/dist/storage/providers/filecoin/index.d.ts +51 -0
  536. package/dist/storage/providers/filecoin/index.js +103 -0
  537. package/dist/storage/providers/filecoin/ipfs-cid.d.ts +50 -0
  538. package/dist/storage/providers/filecoin/ipfs-cid.js +64 -0
  539. package/dist/storage/providers/filecoin/metadata.d.ts +72 -0
  540. package/dist/storage/providers/filecoin/metadata.js +137 -0
  541. package/dist/storage/providers/filecoin/piece-cid.d.ts +48 -0
  542. package/dist/storage/providers/filecoin/piece-cid.js +57 -0
  543. package/dist/storage/providers/filecoin/provider-client.d.ts +234 -0
  544. package/dist/storage/providers/filecoin/provider-client.js +27 -0
  545. package/dist/storage/providers/filecoin/readiness.d.ts +62 -0
  546. package/dist/storage/providers/filecoin/readiness.js +85 -0
  547. package/dist/storage/providers/filecoin/retriever.d.ts +82 -0
  548. package/dist/storage/providers/filecoin/retriever.js +63 -0
  549. package/dist/storage/providers/filecoin/skeleton-client.d.ts +36 -0
  550. package/dist/storage/providers/filecoin/skeleton-client.js +55 -0
  551. package/dist/storage/providers/filecoin/synapse-client.d.ts +169 -0
  552. package/dist/storage/providers/filecoin/synapse-client.js +343 -0
  553. package/dist/storage/providers/filecoin/synapse-construction.d.ts +26 -0
  554. package/dist/storage/providers/filecoin/synapse-construction.js +47 -0
  555. package/dist/storage/providers/filecoin/synapse-error-mapping.d.ts +23 -0
  556. package/dist/storage/providers/filecoin/synapse-error-mapping.js +49 -0
  557. package/dist/storage/providers/filecoin/synapse-readiness.d.ts +37 -0
  558. package/dist/storage/providers/filecoin/synapse-readiness.js +231 -0
  559. package/dist/storage/providers/filecoin/uri.d.ts +49 -0
  560. package/dist/storage/providers/filecoin/uri.js +84 -0
  561. package/dist/storage/providers/filecoin/verified-fetch-lifecycle.d.ts +77 -0
  562. package/dist/storage/providers/filecoin/verified-fetch-lifecycle.js +196 -0
  563. package/dist/storage/providers/filecoin/verified-fetch-retriever.d.ts +54 -0
  564. package/dist/storage/providers/filecoin/verified-fetch-retriever.js +81 -0
  565. package/dist/storage/providers/filecoin/verified-fetch-vendor.d.ts +71 -0
  566. package/dist/storage/providers/filecoin/verified-fetch-vendor.js +94 -0
  567. package/dist/storage/raw-content-codec.d.ts +89 -0
  568. package/dist/storage/raw-content-codec.js +47 -0
  569. package/dist/storage/raw-content-store-backend-adapter.d.ts +28 -0
  570. package/dist/storage/raw-content-store-backend-adapter.js +67 -0
  571. package/dist/storage/raw-content-store.d.ts +228 -0
  572. package/dist/storage/raw-content-store.js +27 -0
  573. package/dist/storage/s3-store.d.ts +42 -0
  574. package/dist/storage/s3-store.js +181 -0
  575. package/dist/storage/storage-backend-registry.d.ts +58 -0
  576. package/dist/storage/storage-backend-registry.js +56 -0
  577. package/dist/storage/storage-backend.d.ts +82 -0
  578. package/dist/storage/storage-backend.js +14 -0
  579. package/dist/storage/storage-capabilities.d.ts +56 -0
  580. package/dist/storage/storage-capabilities.js +170 -0
  581. package/dist/storage/store-registry.d.ts +67 -0
  582. package/dist/storage/store-registry.js +77 -0
  583. package/dist/vector-math.d.ts +15 -0
  584. package/dist/vector-math.js +31 -0
  585. package/dist/xml-escape.d.ts +5 -0
  586. package/dist/xml-escape.js +7 -0
  587. package/openapi.json +15395 -0
  588. package/openapi.yaml +10794 -0
  589. package/package.json +119 -0
package/dist/config.js ADDED
@@ -0,0 +1,808 @@
1
+ /**
2
+ * Runtime configuration for the prototype backend.
3
+ * Loads validated env-backed defaults, then allows limited in-memory updates
4
+ * for local UI experimentation via PUT /v1/memories/config.
5
+ */
6
+ import { getRetrievalProfile, parseRetrievalProfile, } from './services/retrieval-profiles.js';
7
+ import { parsePointerUriSchemes } from './storage/pointer-uri-allowlist.js';
8
+ import { collectFilecoinProviderEnvKeys, parseFilecoinProviderConfig, } from './storage/providers/filecoin/config.js';
9
+ function requireEnv(name) {
10
+ const value = process.env[name];
11
+ if (!value) {
12
+ throw new Error(`Missing required environment variable: ${name}`);
13
+ }
14
+ return value;
15
+ }
16
+ function optionalEnv(name) {
17
+ return process.env[name] || undefined;
18
+ }
19
+ function parseEmbeddingProvider(value, fallback) {
20
+ if (!value)
21
+ return fallback;
22
+ const valid = ['openai', 'ollama', 'openai-compatible', 'transformers', 'voyage'];
23
+ if (!valid.includes(value)) {
24
+ throw new Error(`Invalid provider "${value}". Must be one of: ${valid.join(', ')}`);
25
+ }
26
+ return value;
27
+ }
28
+ function parseLlmProvider(value, fallback) {
29
+ if (!value)
30
+ return fallback;
31
+ const valid = [
32
+ 'openai',
33
+ 'ollama',
34
+ 'openai-compatible',
35
+ 'groq',
36
+ 'anthropic',
37
+ 'google-genai',
38
+ 'claude-code',
39
+ ];
40
+ if (!valid.includes(value)) {
41
+ throw new Error(`Invalid provider "${value}". Must be one of: ${valid.join(', ')}`);
42
+ }
43
+ return value;
44
+ }
45
+ function defaultLlmModel(provider) {
46
+ if (provider === 'claude-code')
47
+ return '';
48
+ return 'gpt-4o-mini';
49
+ }
50
+ function requireFiniteNumber(value, field) {
51
+ if (!Number.isFinite(value)) {
52
+ throw new Error(`${field} must be a finite number`);
53
+ }
54
+ return value;
55
+ }
56
+ function parseCrossEncoderDtype(value) {
57
+ const dtype = value ?? 'auto';
58
+ const valid = ['auto', 'fp32', 'fp16', 'q8', 'int8', 'uint8', 'q4', 'bnb4', 'q4f16'];
59
+ if (!valid.includes(dtype)) {
60
+ throw new Error(`Invalid CROSS_ENCODER_DTYPE "${dtype}". Must be one of: ${valid.join(', ')}`);
61
+ }
62
+ return dtype;
63
+ }
64
+ function parseLlmSeed(value) {
65
+ if (!value)
66
+ return undefined;
67
+ const parsed = parseInt(value, 10);
68
+ return Number.isFinite(parsed) ? parsed : undefined;
69
+ }
70
+ function parsePositiveIntEnv(name, fallback) {
71
+ const raw = optionalEnv(name);
72
+ if (!raw)
73
+ return fallback;
74
+ const parsed = parseInt(raw, 10);
75
+ if (!Number.isFinite(parsed) || parsed < 1) {
76
+ throw new Error(`${name} must be a positive integer`);
77
+ }
78
+ return parsed;
79
+ }
80
+ function parseVectorBackend(value) {
81
+ if (!value)
82
+ return 'pgvector';
83
+ if (value === 'pgvector' || value === 'ruvector-mock' || value === 'zvec-mock')
84
+ return value;
85
+ throw new Error('Invalid VECTOR_BACKEND. Must be "pgvector", "ruvector-mock", or "zvec-mock"');
86
+ }
87
+ /**
88
+ * Phases 1 + 3 of the large-file ingestion plan accept `pointer_only`
89
+ * and `managed_blob` respectively. `inline_small_text` is reserved for
90
+ * a later phase — fail closed rather than silently downgrading if an
91
+ * operator sets it now.
92
+ */
93
+ function parseRawStorageMode(value) {
94
+ if (!value || value === 'pointer_only')
95
+ return 'pointer_only';
96
+ if (value === 'managed_blob')
97
+ return 'managed_blob';
98
+ if (value === 'inline_small_text') {
99
+ throw new Error("RAW_STORAGE_MODE='inline_small_text' is not yet supported. Use " +
100
+ "'pointer_only' or 'managed_blob'.");
101
+ }
102
+ throw new Error(`Invalid RAW_STORAGE_MODE '${value}'. Must be 'pointer_only' or 'managed_blob'.`);
103
+ }
104
+ /** Parse + validate RAW_STORAGE_PROVIDER for `managed_blob` mode. */
105
+ function parseRawStorageProvider(value) {
106
+ if (!value)
107
+ return null;
108
+ if (value === 'local_fs' || value === 's3' || value === 'filecoin')
109
+ return value;
110
+ throw new Error(`Invalid RAW_STORAGE_PROVIDER '${value}'. Must be 'local_fs', 's3', or 'filecoin'.`);
111
+ }
112
+ /** Parse `RAW_CONTENT_CODEC` env var. Defaults to `'none'`. */
113
+ function parseRawContentCodec(value) {
114
+ if (!value)
115
+ return 'none';
116
+ if (value === 'none' || value === 'aes_gcm')
117
+ return value;
118
+ throw new Error(`Invalid RAW_CONTENT_CODEC '${value}'. Must be 'none' or 'aes_gcm'.`);
119
+ }
120
+ /**
121
+ * Parse `RAW_CONTENT_CODEC_KEYS` env var: comma-separated `keyId:base64Url`
122
+ * pairs. Each decoded key MUST be exactly 32 bytes (AES-256). Empty
123
+ * input returns an empty ring (validation runs separately).
124
+ */
125
+ function parseRawContentCodecKeys(value) {
126
+ const ring = new Map();
127
+ if (!value)
128
+ return ring;
129
+ const entries = value.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
130
+ for (const entry of entries) {
131
+ const colon = entry.indexOf(':');
132
+ if (colon <= 0) {
133
+ throw new Error(`RAW_CONTENT_CODEC_KEYS entry '${entry}' must be '<keyId>:<base64Url-32B>'.`);
134
+ }
135
+ const keyId = entry.slice(0, colon);
136
+ const encoded = entry.slice(colon + 1);
137
+ let key;
138
+ try {
139
+ key = Buffer.from(encoded, 'base64url');
140
+ }
141
+ catch {
142
+ throw new Error(`RAW_CONTENT_CODEC_KEYS entry for '${keyId}' is not valid base64url.`);
143
+ }
144
+ if (key.length !== 32) {
145
+ throw new Error(`RAW_CONTENT_CODEC_KEYS entry for '${keyId}' decoded to ${key.length} bytes; expected 32.`);
146
+ }
147
+ if (ring.has(keyId)) {
148
+ throw new Error(`Duplicate keyId '${keyId}' in RAW_CONTENT_CODEC_KEYS.`);
149
+ }
150
+ ring.set(keyId, key);
151
+ }
152
+ return ring;
153
+ }
154
+ /** Parse the required `RAW_STORAGE_DEPLOYMENT_ENV` knob. */
155
+ function parseRawStorageDeploymentEnv(value) {
156
+ if (!value) {
157
+ throw new Error("RAW_STORAGE_DEPLOYMENT_ENV is required. Set 'production', 'staging', or 'local'.");
158
+ }
159
+ if (value === 'production' || value === 'staging' || value === 'local')
160
+ return value;
161
+ throw new Error(`Invalid RAW_STORAGE_DEPLOYMENT_ENV '${value}'. Must be 'production', 'staging', or 'local'.`);
162
+ }
163
+ /**
164
+ * Parse `RAW_STORAGE_LEGACY_PROVIDERS` (csv). The active provider is
165
+ * NEVER allowed in this list — that check happens in
166
+ * `validateRawStorageConfig` since it requires knowing which provider
167
+ * is active. Unknown values fail closed here so typos surface.
168
+ */
169
+ function parseLegacyProviders(value) {
170
+ if (!value)
171
+ return [];
172
+ const entries = value.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
173
+ const out = [];
174
+ const seen = new Set();
175
+ for (const entry of entries) {
176
+ if (entry !== 'local_fs' && entry !== 's3' && entry !== 'filecoin') {
177
+ throw new Error(`Invalid RAW_STORAGE_LEGACY_PROVIDERS entry '${entry}'. ` +
178
+ "Each item must be 'local_fs', 's3', or 'filecoin'.");
179
+ }
180
+ if (seen.has(entry)) {
181
+ throw new Error(`Duplicate provider '${entry}' in RAW_STORAGE_LEGACY_PROVIDERS.`);
182
+ }
183
+ seen.add(entry);
184
+ out.push(entry);
185
+ }
186
+ return out;
187
+ }
188
+ /**
189
+ * Phase-3 plan requires every managed blob to live under a namespaced
190
+ * path including environment, user, and document ids. The user/doc
191
+ * portion is generated per-upload; the environment portion is the
192
+ * `RAW_STORAGE_PREFIX` operator-supplied namespace. Validate that the
193
+ * prefix is a non-empty *relative* path with no `..` segments before
194
+ * it gets joined with caller-controlled key fragments.
195
+ */
196
+ function validateRawStoragePrefix(prefix) {
197
+ if (!prefix || prefix.trim().length === 0) {
198
+ throw new Error("RAW_STORAGE_MODE='managed_blob' requires RAW_STORAGE_PREFIX " +
199
+ '(a relative namespace path, e.g. `prod/core`).');
200
+ }
201
+ if (prefix.startsWith('/')) {
202
+ throw new Error("RAW_STORAGE_PREFIX must be a relative path (no leading '/').");
203
+ }
204
+ const segments = prefix.split('/').filter((s) => s.length > 0);
205
+ if (segments.some((s) => s === '..')) {
206
+ throw new Error("RAW_STORAGE_PREFIX must not contain '..' segments.");
207
+ }
208
+ }
209
+ export function validateRawStorageConfig(args) {
210
+ validateCodecConfig(args);
211
+ validateLegacyProviders(args);
212
+ rejectFilecoinEnvOnNonFilecoinProvider(args);
213
+ if (args.mode !== 'managed_blob') {
214
+ if (args.provider !== null) {
215
+ throw new Error("RAW_STORAGE_PROVIDER is set but RAW_STORAGE_MODE is not 'managed_blob'. " +
216
+ "Either set RAW_STORAGE_MODE='managed_blob' or unset RAW_STORAGE_PROVIDER.");
217
+ }
218
+ return;
219
+ }
220
+ if (!args.provider) {
221
+ throw new Error("RAW_STORAGE_MODE='managed_blob' requires RAW_STORAGE_PROVIDER " +
222
+ "('local_fs', 's3', or 'filecoin').");
223
+ }
224
+ validateRawStoragePrefix(args.prefix);
225
+ if (args.provider === 'local_fs') {
226
+ if (!args.localFsRoot) {
227
+ throw new Error("RAW_STORAGE_PROVIDER='local_fs' requires RAW_STORAGE_LOCAL_FS_ROOT.");
228
+ }
229
+ return;
230
+ }
231
+ if (args.provider === 's3') {
232
+ const missing = collectMissingS3Fields(args);
233
+ if (missing.length > 0) {
234
+ throw new Error(`RAW_STORAGE_PROVIDER='s3' requires: ${missing.join(', ')}.`);
235
+ }
236
+ return;
237
+ }
238
+ // provider === 'filecoin'. Synapse-shaped env validation lives in
239
+ // `parseFilecoinProviderConfig` (called from this file's config
240
+ // init block below) so the provider module is the single source
241
+ // of truth for its own field shape. The cross-provider guard fires
242
+ // BEFORE this branch so a misconfigured non-filecoin deployment
243
+ // carrying stray Filecoin vars fails fast.
244
+ }
245
+ /**
246
+ * Reject any `RAW_STORAGE_FILECOIN_*` environment variable that is
247
+ * set when `RAW_STORAGE_PROVIDER` is not `'filecoin'`. The provider
248
+ * module's parser is only invoked on the filecoin branch, so this
249
+ * central guard is the only seam that catches "operator left stale
250
+ * Filecoin config on an S3 deployment" misconfigurations.
251
+ */
252
+ function rejectFilecoinEnvOnNonFilecoinProvider(args) {
253
+ if (args.provider === 'filecoin')
254
+ return;
255
+ if (args.filecoinEnvKeysSet.length === 0)
256
+ return;
257
+ throw new Error(`RAW_STORAGE_FILECOIN_* environment variables are set but ` +
258
+ `RAW_STORAGE_PROVIDER='${args.provider ?? '<unset>'}'. ` +
259
+ `Filecoin provider configuration is only valid when ` +
260
+ `RAW_STORAGE_PROVIDER=filecoin. Unset: ${args.filecoinEnvKeysSet.join(', ')}.`);
261
+ }
262
+ function collectMissingS3Fields(args) {
263
+ return [
264
+ !args.s3Bucket && 'RAW_STORAGE_S3_BUCKET',
265
+ !args.s3Region && 'RAW_STORAGE_S3_REGION',
266
+ !args.s3AccessKeyId && 'RAW_STORAGE_S3_ACCESS_KEY_ID',
267
+ !args.s3SecretAccessKey && 'RAW_STORAGE_S3_SECRET_ACCESS_KEY',
268
+ ].filter((x) => Boolean(x));
269
+ }
270
+ function collectMissingLocalFsFields(args) {
271
+ return args.localFsRoot ? [] : ['RAW_STORAGE_LOCAL_FS_ROOT'];
272
+ }
273
+ /**
274
+ * Codec-level validation independent of the active provider: if the
275
+ * operator selected `aes_gcm`, they MUST configure a non-empty keyring
276
+ * and an active key id present in that ring. Misconfiguration fails
277
+ * closed at startup rather than at first encode.
278
+ */
279
+ function validateCodecConfig(args) {
280
+ if (args.codec !== 'aes_gcm') {
281
+ if (args.codecKeys.size > 0 || args.codecActiveKeyId !== null) {
282
+ throw new Error("RAW_CONTENT_CODEC is not 'aes_gcm' but codec keyring fields are set. " +
283
+ "Either set RAW_CONTENT_CODEC='aes_gcm' or unset RAW_CONTENT_CODEC_KEYS/_ACTIVE_KEY_ID.");
284
+ }
285
+ return;
286
+ }
287
+ if (args.codecKeys.size === 0) {
288
+ throw new Error("RAW_CONTENT_CODEC='aes_gcm' requires RAW_CONTENT_CODEC_KEYS (non-empty).");
289
+ }
290
+ if (!args.codecActiveKeyId) {
291
+ throw new Error("RAW_CONTENT_CODEC='aes_gcm' requires RAW_CONTENT_CODEC_ACTIVE_KEY_ID.");
292
+ }
293
+ if (!args.codecKeys.has(args.codecActiveKeyId)) {
294
+ throw new Error(`RAW_CONTENT_CODEC_ACTIVE_KEY_ID='${args.codecActiveKeyId}' is not present in RAW_CONTENT_CODEC_KEYS.`);
295
+ }
296
+ }
297
+ /**
298
+ * `RAW_STORAGE_LEGACY_PROVIDERS` validation: every named provider must
299
+ * have its full env block configured, must NOT equal the active
300
+ * provider, and cannot include `'filecoin'` (which is the canonical
301
+ * active-only provider for this iteration; legacy Filecoin rows are
302
+ * handled by the active store directly).
303
+ */
304
+ function validateLegacyProviders(args) {
305
+ for (const provider of args.legacyProviders) {
306
+ if (provider === args.provider) {
307
+ throw new Error(`RAW_STORAGE_LEGACY_PROVIDERS lists '${provider}', but that is the active provider. ` +
308
+ 'A provider cannot be both active and legacy.');
309
+ }
310
+ if (provider === 'filecoin') {
311
+ throw new Error(`RAW_STORAGE_LEGACY_PROVIDERS cannot include '${provider}'. ` +
312
+ 'Filecoin-family rows are served by the active store, not via legacy registration.');
313
+ }
314
+ const missing = provider === 'local_fs'
315
+ ? collectMissingLocalFsFields(args)
316
+ : collectMissingS3Fields(args);
317
+ if (missing.length > 0) {
318
+ throw new Error(`RAW_STORAGE_LEGACY_PROVIDERS='${provider}' requires its full env block: ${missing.join(', ')}.`);
319
+ }
320
+ }
321
+ }
322
+ const embeddingProvider = parseEmbeddingProvider(optionalEnv('EMBEDDING_PROVIDER'), 'openai');
323
+ const llmProvider = parseLlmProvider(optionalEnv('LLM_PROVIDER'), 'openai');
324
+ const retrievalProfile = parseRetrievalProfile(optionalEnv('RETRIEVAL_PROFILE'));
325
+ const retrievalProfileSettings = getRetrievalProfile(retrievalProfile);
326
+ const DEFAULT_SIMILARITY_THRESHOLD = 0.3;
327
+ /** Require OpenAI key only when at least one provider uses it. */
328
+ const needsOpenAIKey = embeddingProvider === 'openai' || llmProvider === 'openai';
329
+ const needsGroqKey = llmProvider === 'groq';
330
+ const needsAnthropicKey = llmProvider === 'anthropic';
331
+ const needsGoogleKey = llmProvider === 'google-genai';
332
+ const needsVoyageKey = embeddingProvider === 'voyage';
333
+ const groqApiKey = needsGroqKey ? requireEnv('GROQ_API_KEY') : optionalEnv('GROQ_API_KEY');
334
+ const openaiApiKey = needsOpenAIKey ? requireEnv('OPENAI_API_KEY') : (optionalEnv('OPENAI_API_KEY') ?? '');
335
+ const anthropicApiKey = needsAnthropicKey ? requireEnv('ANTHROPIC_API_KEY') : optionalEnv('ANTHROPIC_API_KEY');
336
+ const googleApiKey = needsGoogleKey ? requireEnv('GOOGLE_API_KEY') : optionalEnv('GOOGLE_API_KEY');
337
+ const voyageApiKey = needsVoyageKey ? requireEnv('VOYAGE_API_KEY') : optionalEnv('VOYAGE_API_KEY');
338
+ /**
339
+ * Validate the hex-encoded HMAC secret used for storage-key prefix
340
+ * derivation. Rejects values shorter than 64 hex chars (32 bytes) or
341
+ * containing non-hex characters. Empty / missing values are caught
342
+ * by `requireEnv` before this function runs.
343
+ */
344
+ function parseStorageKeyHmacSecret(raw) {
345
+ const value = raw.trim();
346
+ if (value.length < 64) {
347
+ throw new Error('STORAGE_KEY_HMAC_SECRET must be at least 64 hex chars (32 bytes of entropy).');
348
+ }
349
+ if (!/^[0-9a-fA-F]+$/.test(value)) {
350
+ throw new Error('STORAGE_KEY_HMAC_SECRET must be hex-encoded.');
351
+ }
352
+ return value.toLowerCase();
353
+ }
354
+ function parseUnitNumberEnv(name, fallback) {
355
+ const raw = optionalEnv(name);
356
+ if (!raw)
357
+ return fallback;
358
+ const parsed = Number.parseFloat(raw);
359
+ if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
360
+ throw new Error(`${name} must be a finite number between 0 and 1`);
361
+ }
362
+ return parsed;
363
+ }
364
+ export const config = {
365
+ databaseUrl: requireEnv('DATABASE_URL'),
366
+ openaiApiKey,
367
+ coreApiKey: requireEnv('CORE_API_KEY'),
368
+ storageKeyHmacSecret: parseStorageKeyHmacSecret(requireEnv('STORAGE_KEY_HMAC_SECRET')),
369
+ port: parseInt(process.env.PORT ?? '3050', 10),
370
+ retrievalProfile,
371
+ retrievalProfileSettings,
372
+ maxSearchResults: retrievalProfileSettings.maxSearchResults,
373
+ similarityThreshold: parseUnitNumberEnv('SIMILARITY_THRESHOLD', DEFAULT_SIMILARITY_THRESHOLD),
374
+ audnCandidateThreshold: parseFloat(optionalEnv('AUDN_CANDIDATE_THRESHOLD') ?? '0.7'),
375
+ audnSafeReuseMinSimilarity: parseFloat(optionalEnv('AUDN_SAFE_REUSE_MIN_SIMILARITY') ?? '0.95'),
376
+ crossAgentCandidateThreshold: parseFloat(optionalEnv('CROSS_AGENT_CANDIDATE_THRESHOLD') ?? '0.75'),
377
+ clarificationConflictThreshold: 0.8,
378
+ adaptiveRetrievalEnabled: (process.env.ADAPTIVE_RETRIEVAL_ENABLED ?? String(retrievalProfileSettings.adaptiveRetrievalEnabled)) === 'true',
379
+ adaptiveSimpleLimit: parsePositiveIntEnv('ADAPTIVE_SIMPLE_LIMIT', 5),
380
+ adaptiveMediumLimit: parsePositiveIntEnv('ADAPTIVE_MEDIUM_LIMIT', 5),
381
+ adaptiveComplexLimit: parsePositiveIntEnv('ADAPTIVE_COMPLEX_LIMIT', 8),
382
+ adaptiveMultiHopLimit: parsePositiveIntEnv('ADAPTIVE_MULTI_HOP_LIMIT', 12),
383
+ adaptiveAggregationLimit: parsePositiveIntEnv('ADAPTIVE_AGGREGATION_LIMIT', 25),
384
+ repairLoopEnabled: (process.env.REPAIR_LOOP_ENABLED ?? String(retrievalProfileSettings.repairLoopEnabled)) === 'true',
385
+ hybridSearchEnabled: (process.env.HYBRID_SEARCH_ENABLED ?? String(retrievalProfileSettings.hybridSearchEnabled)) === 'true',
386
+ repairLoopMinSimilarity: parseFloat(process.env.REPAIR_LOOP_MIN_SIMILARITY ?? String(retrievalProfileSettings.repairLoopMinSimilarity)),
387
+ repairSkipSimilarity: parseFloat(process.env.REPAIR_SKIP_SIMILARITY ?? String(retrievalProfileSettings.repairSkipSimilarity ?? 0.55)),
388
+ mmrEnabled: (process.env.MMR_ENABLED ?? String(retrievalProfileSettings.mmrEnabled)) === 'true',
389
+ mmrLambda: parseFloat(process.env.MMR_LAMBDA ?? String(retrievalProfileSettings.mmrLambda)),
390
+ linkExpansionEnabled: (process.env.LINK_EXPANSION_ENABLED ?? String(retrievalProfileSettings.linkExpansionEnabled)) === 'true',
391
+ linkExpansionMax: parseInt(process.env.LINK_EXPANSION_MAX ?? String(retrievalProfileSettings.linkExpansionMax), 10),
392
+ linkSimilarityThreshold: parseFloat(process.env.LINK_SIMILARITY_THRESHOLD ?? String(retrievalProfileSettings.linkSimilarityThreshold)),
393
+ scoringWeightSimilarity: parseFloat(process.env.SCORING_WEIGHT_SIMILARITY ?? String(retrievalProfileSettings.scoringWeightSimilarity)),
394
+ scoringWeightImportance: parseFloat(process.env.SCORING_WEIGHT_IMPORTANCE ?? String(retrievalProfileSettings.scoringWeightImportance)),
395
+ scoringWeightRecency: parseFloat(process.env.SCORING_WEIGHT_RECENCY ?? String(retrievalProfileSettings.scoringWeightRecency)),
396
+ linkExpansionBeforeMMR: (process.env.LINK_EXPANSION_BEFORE_MMR ?? String(retrievalProfileSettings.linkExpansionBeforeMMR)) === 'true',
397
+ pprEnabled: (process.env.PPR_ENABLED ?? 'false') === 'true',
398
+ pprDamping: parseFloat(process.env.PPR_DAMPING ?? '0.5'),
399
+ repairDeltaThreshold: parseFloat(process.env.REPAIR_DELTA_THRESHOLD ?? String(retrievalProfileSettings.repairDeltaThreshold)),
400
+ repairConfidenceFloor: parseFloat(process.env.REPAIR_CONFIDENCE_FLOOR ?? String(retrievalProfileSettings.repairConfidenceFloor)),
401
+ // Embedding provider
402
+ embeddingProvider,
403
+ embeddingModel: optionalEnv('EMBEDDING_MODEL') ?? 'text-embedding-3-small',
404
+ embeddingDimensions: parseInt(requireEnv('EMBEDDING_DIMENSIONS'), 10),
405
+ embeddingApiUrl: optionalEnv('EMBEDDING_API_URL'),
406
+ embeddingApiKey: optionalEnv('EMBEDDING_API_KEY'),
407
+ voyageApiKey: voyageApiKey ?? undefined,
408
+ voyageDocumentModel: optionalEnv('VOYAGE_DOCUMENT_MODEL') ?? 'voyage-4-large',
409
+ voyageQueryModel: optionalEnv('VOYAGE_QUERY_MODEL') ?? 'voyage-4-lite',
410
+ // LLM provider
411
+ llmProvider,
412
+ llmModel: optionalEnv('LLM_MODEL') ?? defaultLlmModel(llmProvider),
413
+ llmApiUrl: optionalEnv('LLM_API_URL'),
414
+ llmApiKey: optionalEnv('LLM_API_KEY'),
415
+ // Groq
416
+ groqApiKey: groqApiKey ?? undefined,
417
+ anthropicApiKey: anthropicApiKey ?? undefined,
418
+ googleApiKey: googleApiKey ?? undefined,
419
+ // Ollama
420
+ ollamaBaseUrl: optionalEnv('OLLAMA_BASE_URL') ?? 'http://localhost:11434',
421
+ vectorBackend: parseVectorBackend(optionalEnv('VECTOR_BACKEND')),
422
+ skipVectorIndexes: (optionalEnv('SKIP_VECTOR_INDEXES') ?? 'false') === 'true',
423
+ llmSeed: parseLlmSeed(optionalEnv('LLM_SEED')),
424
+ stagedLoadingEnabled: (optionalEnv('STAGED_LOADING_ENABLED') ?? 'false') === 'true',
425
+ retrievalTraceEnabled: (optionalEnv('RETRIEVAL_TRACE_ENABLED') ?? 'false') === 'true',
426
+ ingestTraceDir: optionalEnv('INGEST_TRACE_DIR') ?? './.traces/ingest',
427
+ ingestTraceEnabled: (optionalEnv('INGEST_TRACE_ENABLED') ?? 'false') === 'true',
428
+ extractionCacheEnabled: (optionalEnv('EXTRACTION_CACHE_ENABLED') ?? 'false') === 'true',
429
+ extractionCacheDir: optionalEnv('EXTRACTION_CACHE_DIR') ?? './.eval-cache',
430
+ embeddingCacheEnabled: (optionalEnv('EMBEDDING_CACHE_ENABLED') ?? 'false') === 'true',
431
+ chunkedExtractionEnabled: (optionalEnv('CHUNKED_EXTRACTION_ENABLED') ?? 'false') === 'true',
432
+ chunkedExtractionFallbackEnabled: (optionalEnv('CHUNKED_EXTRACTION_FALLBACK_ENABLED') ?? 'false') === 'true',
433
+ chunkSizeTurns: parseInt(optionalEnv('CHUNK_SIZE_TURNS') ?? '4', 10),
434
+ chunkOverlapTurns: parseInt(optionalEnv('CHUNK_OVERLAP_TURNS') ?? '1', 10),
435
+ consensusExtractionEnabled: (optionalEnv('CONSENSUS_EXTRACTION_ENABLED') ?? 'false') === 'true',
436
+ consensusExtractionRuns: parseInt(optionalEnv('CONSENSUS_EXTRACTION_RUNS') ?? '3', 10),
437
+ observationDateExtractionEnabled: (optionalEnv('OBSERVATION_DATE_EXTRACTION_ENABLED') ?? 'false') === 'true',
438
+ quotedEntityExtractionEnabled: (optionalEnv('QUOTED_ENTITY_EXTRACTION_ENABLED') ?? 'false') === 'true',
439
+ entropyGateEnabled: (optionalEnv('ENTROPY_GATE_ENABLED') ?? 'false') === 'true',
440
+ entropyGateThreshold: parseFloat(optionalEnv('ENTROPY_GATE_THRESHOLD') ?? '0.35'),
441
+ entropyGateAlpha: parseFloat(optionalEnv('ENTROPY_GATE_ALPHA') ?? '0.5'),
442
+ affinityClusteringThreshold: parseFloat(optionalEnv('AFFINITY_CLUSTERING_THRESHOLD') ?? '0.85'),
443
+ affinityClusteringMinSize: parseInt(optionalEnv('AFFINITY_CLUSTERING_MIN_SIZE') ?? '3', 10),
444
+ affinityClusteringBeta: parseFloat(optionalEnv('AFFINITY_CLUSTERING_BETA') ?? '0.5'),
445
+ affinityClusteringTemporalLambda: parseFloat(optionalEnv('AFFINITY_CLUSTERING_TEMPORAL_LAMBDA') ?? '0.1'),
446
+ trustScoringEnabled: (optionalEnv('TRUST_SCORING_ENABLED') ?? 'false') === 'true',
447
+ trustScoreMinThreshold: parseFloat(optionalEnv('TRUST_SCORE_MIN_THRESHOLD') ?? '0.3'),
448
+ trustPenaltyEnabled: (optionalEnv('TRUST_PENALTY_ENABLED') ?? 'false') === 'true',
449
+ auditLoggingEnabled: (optionalEnv('AUDIT_LOGGING_ENABLED') ?? 'false') === 'true',
450
+ decayCycleEnabled: (optionalEnv('DECAY_CYCLE_ENABLED') ?? 'false') === 'true',
451
+ decayRetentionThreshold: parseFloat(optionalEnv('DECAY_RETENTION_THRESHOLD') ?? '0.2'),
452
+ decayMinAgeDays: parseInt(optionalEnv('DECAY_MIN_AGE_DAYS') ?? '7', 10),
453
+ memoryCapEnabled: (optionalEnv('MEMORY_CAP_ENABLED') ?? 'false') === 'true',
454
+ memoryCapMax: parseInt(optionalEnv('MEMORY_CAP_MAX') ?? '5000', 10),
455
+ memoryCapWarnRatio: parseFloat(optionalEnv('MEMORY_CAP_WARN_RATIO') ?? '0.8'),
456
+ entityGraphEnabled: (optionalEnv('ENTITY_GRAPH_ENABLED') ?? 'false') === 'true',
457
+ entityResolutionThreshold: parseFloat(optionalEnv('ENTITY_RESOLUTION_THRESHOLD') ?? '0.92'),
458
+ entitySearchMinSimilarity: parseFloat(optionalEnv('ENTITY_SEARCH_MIN_SIMILARITY') ?? '0.7'),
459
+ lessonsEnabled: (optionalEnv('LESSONS_ENABLED') ?? 'false') === 'true',
460
+ lessonSimilarityThreshold: parseFloat(optionalEnv('LESSON_SIMILARITY_THRESHOLD') ?? '0.75'),
461
+ consensusValidationEnabled: (optionalEnv('CONSENSUS_VALIDATION_ENABLED') ?? 'false') === 'true',
462
+ consensusMinMemories: parseInt(optionalEnv('CONSENSUS_MIN_MEMORIES') ?? '3', 10),
463
+ queryExpansionEnabled: (optionalEnv('QUERY_EXPANSION_ENABLED') ?? 'false') === 'true',
464
+ queryExpansionMinSimilarity: parseFloat(optionalEnv('QUERY_EXPANSION_MIN_SIMILARITY') ?? '0.5'),
465
+ queryAugmentationEnabled: (optionalEnv('QUERY_AUGMENTATION_ENABLED') ?? 'false') === 'true',
466
+ queryAugmentationMaxEntities: parseInt(optionalEnv('QUERY_AUGMENTATION_MAX_ENTITIES') ?? '5', 10),
467
+ queryAugmentationMinSimilarity: parseFloat(optionalEnv('QUERY_AUGMENTATION_MIN_SIMILARITY') ?? '0.4'),
468
+ crossEncoderEnabled: (optionalEnv('CROSS_ENCODER_ENABLED') ?? 'false') === 'true', // ms-marco hurts temporal queries; keep disabled until better model
469
+ crossEncoderModel: optionalEnv('CROSS_ENCODER_MODEL') ?? 'Xenova/ms-marco-MiniLM-L-6-v2',
470
+ crossEncoderDtype: parseCrossEncoderDtype(optionalEnv('CROSS_ENCODER_DTYPE')),
471
+ iterativeRetrievalEnabled: (optionalEnv('ITERATIVE_RETRIEVAL_ENABLED') ?? 'false') === 'true',
472
+ namespaceClassificationEnabled: (optionalEnv('NAMESPACE_CLASSIFICATION_ENABLED') ?? 'false') === 'true',
473
+ fastAudnEnabled: (optionalEnv('FAST_AUDN_ENABLED') ?? 'true') === 'true',
474
+ fastAudnDuplicateThreshold: parseFloat(optionalEnv('FAST_AUDN_DUPLICATE_THRESHOLD') ?? '0.95'),
475
+ observationNetworkEnabled: (optionalEnv('OBSERVATION_NETWORK_ENABLED') ?? 'true') === 'true',
476
+ agenticRetrievalEnabled: (optionalEnv('AGENTIC_RETRIEVAL_ENABLED') ?? 'false') === 'true',
477
+ rerankSkipTopSimilarity: parseFloat(optionalEnv('RERANK_SKIP_TOP_SIMILARITY') ?? '0.85'),
478
+ rerankSkipMinGap: parseFloat(optionalEnv('RERANK_SKIP_MIN_GAP') ?? '0.05'),
479
+ literalListProtectionEnabled: (optionalEnv('LITERAL_LIST_PROTECTION_ENABLED') ?? 'false') === 'true',
480
+ literalListProtectionMaxProtected: parsePositiveIntEnv('LITERAL_LIST_PROTECTION_MAX_PROTECTED', 3),
481
+ temporalQueryConstraintEnabled: (optionalEnv('TEMPORAL_QUERY_CONSTRAINT_ENABLED') ?? 'false') === 'true',
482
+ temporalQueryConstraintBoost: parseFloat(optionalEnv('TEMPORAL_QUERY_CONSTRAINT_BOOST') ?? '2'),
483
+ deferredAudnEnabled: (optionalEnv('DEFERRED_AUDN_ENABLED') ?? 'false') === 'true',
484
+ deferredAudnBatchSize: parseInt(optionalEnv('DEFERRED_AUDN_BATCH_SIZE') ?? '20', 10),
485
+ compositeGroupingEnabled: (optionalEnv('COMPOSITE_GROUPING_ENABLED') ?? 'true') === 'true',
486
+ compositeMinClusterSize: parseInt(optionalEnv('COMPOSITE_MIN_CLUSTER_SIZE') ?? '2', 10),
487
+ compositeMaxClusterSize: parseInt(optionalEnv('COMPOSITE_MAX_CLUSTER_SIZE') ?? '3', 10),
488
+ compositeSimilarityThreshold: parseFloat(optionalEnv('COMPOSITE_SIMILARITY_THRESHOLD') ?? '0.55'),
489
+ costLoggingEnabled: (optionalEnv('COST_LOGGING_ENABLED') ?? 'false') === 'true',
490
+ costLogDir: optionalEnv('COST_LOG_DIR') ?? 'data/cost-logs',
491
+ costRunId: optionalEnv('COST_RUN_ID') ?? '',
492
+ conflictAutoResolveMs: parseInt(optionalEnv('CONFLICT_AUTO_RESOLVE_MS') ?? '86400000', 10),
493
+ tbcEnabled: (optionalEnv('TBC_ENABLED') ?? 'false') === 'true',
494
+ hierarchicalRetrievalEnabled: (optionalEnv('HIERARCHICAL_RETRIEVAL_ENABLED') ?? 'false') === 'true',
495
+ topicAbstractionEnabled: (optionalEnv('TOPIC_ABSTRACTION_ENABLED') ?? 'false') === 'true',
496
+ topicSearchEnabled: (optionalEnv('TOPIC_SEARCH_ENABLED') ?? 'false') === 'true',
497
+ rerankerEnabled: (optionalEnv('RERANKER_ENABLED') ?? 'false') === 'true',
498
+ rerankerTopN: parseInt(optionalEnv('RERANKER_TOP_N') ?? '20', 10),
499
+ recapLayerEnabled: (optionalEnv('RECAP_LAYER_ENABLED') ?? 'false') === 'true',
500
+ recapMinClusterSize: parseInt(optionalEnv('RECAP_MIN_CLUSTER_SIZE') ?? '4', 10),
501
+ recapSearchEnabled: (optionalEnv('RECAP_SEARCH_ENABLED') ?? 'false') === 'true',
502
+ recapClusterPivot: (optionalEnv('RECAP_CLUSTER_PIVOT') === 'session' ? 'session' : 'topic'),
503
+ counterEvidenceEnabled: (optionalEnv('COUNTER_EVIDENCE_ENABLED') ?? 'false') === 'true',
504
+ packagingUseObservedAt: (optionalEnv('PACKAGING_USE_OBSERVED_AT') ?? 'false') === 'true',
505
+ packagingDualDate: (optionalEnv('PACKAGING_DUAL_DATE') ?? 'false') === 'true',
506
+ timelineChannelEnabled: (optionalEnv('TIMELINE_CHANNEL_ENABLED') ?? 'false') === 'true',
507
+ answerOnlyRetrievalFilter: (optionalEnv('ANSWER_ONLY_RETRIEVAL_FILTER') ?? 'false') === 'true',
508
+ retrievalDedupEnabled: (optionalEnv('RETRIEVAL_DEDUP_ENABLED') ?? 'false') === 'true',
509
+ keywordRrfWeight: parseFloat(optionalEnv('KEYWORD_RRF_WEIGHT') ?? '1.0'),
510
+ entityAttributesEnabled: (optionalEnv('ENTITY_ATTRIBUTES_ENABLED') ?? 'false') === 'true',
511
+ entityAttributesTopK: parsePositiveIntEnv('ENTITY_ATTRIBUTES_TOP_K', 20),
512
+ userProfileChannelEnabled: (optionalEnv('USER_PROFILE_CHANNEL_ENABLED') ?? 'false') === 'true',
513
+ episodesChannelEnabled: (optionalEnv('EPISODES_CHANNEL_ENABLED') ?? 'false') === 'true',
514
+ episodesChannelTopK: parseInt(optionalEnv('EPISODES_CHANNEL_TOP_K') ?? '2', 10),
515
+ verifierPassEnabled: (optionalEnv('VERIFIER_PASS_ENABLED') ?? 'false') === 'true',
516
+ answerFormatAlignmentEnabled: (optionalEnv('ANSWER_FORMAT_ALIGNMENT_ENABLED') ?? 'false') === 'true',
517
+ eventChainPackagingEnabled: (optionalEnv('EVENT_CHAIN_PACKAGING_ENABLED') ?? 'false') === 'true',
518
+ reflectEnabled: (optionalEnv('REFLECT_ENABLED') ?? 'false') === 'true',
519
+ reflectRetrievalTopK: parsePositiveIntEnv('REFLECT_RETRIEVAL_TOP_K', 3),
520
+ reflectModel: optionalEnv('REFLECT_MODEL') ?? 'claude-sonnet-4-5',
521
+ reflectMaxObservations: parsePositiveIntEnv('REFLECT_MAX_OBSERVATIONS', 12),
522
+ reflectJobPollMs: parsePositiveIntEnv('REFLECT_JOB_POLL_MS', 5000),
523
+ reflectDebounceMs: parsePositiveIntEnv('REFLECT_DEBOUNCE_MS', 60000),
524
+ runtimeConfigMutationEnabled: (process.env.CORE_RUNTIME_CONFIG_MUTATION_ENABLED ?? 'false') === 'true',
525
+ phase2SpecialistsEnabled: (optionalEnv('PHASE2_SPECIALISTS_ENABLED') ?? 'false') === 'true',
526
+ abstentionRescueEnabled: (optionalEnv('ABSTENTION_RESCUE_ENABLED') ?? 'false') === 'true',
527
+ abstentionRescueRetrieveK: parseInt(optionalEnv('ABSTENTION_RESCUE_RETRIEVE_K') ?? '8', 10),
528
+ abstentionRescueSonnetModel: optionalEnv('ABSTENTION_RESCUE_SONNET_MODEL') ?? 'claude-sonnet-4-5',
529
+ confidencePrefixAdaptiveEnabled: (optionalEnv('CONFIDENCE_PREFIX_ADAPTIVE_ENABLED') ?? 'false') === 'true',
530
+ kuRecencySortEnabled: (optionalEnv('KU_RECENCY_SORT_ENABLED') ?? 'false') === 'true',
531
+ msrAggregatorEnabled: (optionalEnv('MSR_AGGREGATOR_ENABLED') ?? 'false') === 'true',
532
+ entityCardEnabled: (optionalEnv('ENTITY_CARD_ENABLED') ?? 'false') === 'true',
533
+ entityCardMaxPerSession: parsePositiveIntEnv('ENTITY_CARD_MAX_PER_SESSION', 5),
534
+ entityCardMinObservations: parsePositiveIntEnv('ENTITY_CARD_MIN_OBSERVATIONS', 3),
535
+ contradictionPreservationEnabled: (optionalEnv('CONTRADICTION_PRESERVATION_ENABLED') ?? 'false') === 'true',
536
+ contradictionSurfacingEnabled: (optionalEnv('CONTRADICTION_SURFACING_ENABLED') ?? 'false') === 'true',
537
+ temporalStateEnabled: (optionalEnv('TEMPORAL_STATE_ENABLED') ?? 'false') === 'true',
538
+ rawStorageMode: parseRawStorageMode(optionalEnv('RAW_STORAGE_MODE')),
539
+ rawStorageProvider: parseRawStorageProvider(optionalEnv('RAW_STORAGE_PROVIDER')),
540
+ rawStoragePrefix: optionalEnv('RAW_STORAGE_PREFIX') ?? '',
541
+ rawStorageLocalFsRoot: optionalEnv('RAW_STORAGE_LOCAL_FS_ROOT') ?? null,
542
+ rawStorageS3Bucket: optionalEnv('RAW_STORAGE_S3_BUCKET') ?? null,
543
+ rawStorageS3Region: optionalEnv('RAW_STORAGE_S3_REGION') ?? null,
544
+ rawStorageS3Endpoint: optionalEnv('RAW_STORAGE_S3_ENDPOINT') ?? null,
545
+ rawStorageS3AccessKeyId: optionalEnv('RAW_STORAGE_S3_ACCESS_KEY_ID') ?? null,
546
+ rawStorageS3SecretAccessKey: optionalEnv('RAW_STORAGE_S3_SECRET_ACCESS_KEY') ?? null,
547
+ rawUploadMaxBytes: parsePositiveIntEnv('RAW_UPLOAD_MAX_BYTES', 26214400 /* 25 MiB */),
548
+ rawContentCodec: parseRawContentCodec(optionalEnv('RAW_CONTENT_CODEC')),
549
+ rawContentCodecKeys: parseRawContentCodecKeys(optionalEnv('RAW_CONTENT_CODEC_KEYS')),
550
+ rawContentCodecActiveKeyId: optionalEnv('RAW_CONTENT_CODEC_ACTIVE_KEY_ID') ?? null,
551
+ rawStorageDeploymentEnv: parseRawStorageDeploymentEnv(optionalEnv('RAW_STORAGE_DEPLOYMENT_ENV')),
552
+ filecoinProvider: null,
553
+ rawStorageLegacyProviders: parseLegacyProviders(optionalEnv('RAW_STORAGE_LEGACY_PROVIDERS')),
554
+ rawStoragePointerUriSchemes: parsePointerUriSchemes(optionalEnv('RAW_STORAGE_POINTER_URI_SCHEMES')),
555
+ };
556
+ const filecoinEnvKeysSet = collectFilecoinProviderEnvKeys(process.env);
557
+ validateRawStorageConfig({
558
+ mode: config.rawStorageMode,
559
+ provider: config.rawStorageProvider,
560
+ prefix: config.rawStoragePrefix,
561
+ localFsRoot: config.rawStorageLocalFsRoot,
562
+ s3Bucket: config.rawStorageS3Bucket,
563
+ s3Region: config.rawStorageS3Region,
564
+ s3AccessKeyId: config.rawStorageS3AccessKeyId,
565
+ s3SecretAccessKey: config.rawStorageS3SecretAccessKey,
566
+ codec: config.rawContentCodec,
567
+ codecKeys: config.rawContentCodecKeys,
568
+ codecActiveKeyId: config.rawContentCodecActiveKeyId,
569
+ deploymentEnv: config.rawStorageDeploymentEnv,
570
+ legacyProviders: config.rawStorageLegacyProviders,
571
+ filecoinEnvKeysSet,
572
+ });
573
+ if (config.rawStorageProvider === 'filecoin') {
574
+ // Cross-provider guard above has already fired for non-filecoin
575
+ // deployments carrying stray RAW_STORAGE_FILECOIN_* vars; this
576
+ // branch validates the full Synapse-shaped block and fails closed
577
+ // on missing / malformed values.
578
+ config.filecoinProvider = parseFilecoinProviderConfig(process.env);
579
+ }
580
+ export function applyRuntimeConfigUpdates(target, updates) {
581
+ const applied = [];
582
+ if (updates.similarityThreshold !== undefined) {
583
+ target.similarityThreshold = requireFiniteNumber(updates.similarityThreshold, 'similarityThreshold');
584
+ applied.push('similarityThreshold');
585
+ }
586
+ if (updates.audnCandidateThreshold !== undefined) {
587
+ target.audnCandidateThreshold = requireFiniteNumber(updates.audnCandidateThreshold, 'audnCandidateThreshold');
588
+ applied.push('audnCandidateThreshold');
589
+ }
590
+ if (updates.clarificationConflictThreshold !== undefined) {
591
+ target.clarificationConflictThreshold = requireFiniteNumber(updates.clarificationConflictThreshold, 'clarificationConflictThreshold');
592
+ applied.push('clarificationConflictThreshold');
593
+ }
594
+ if (updates.maxSearchResults !== undefined) {
595
+ target.maxSearchResults = Math.max(1, Math.floor(requireFiniteNumber(updates.maxSearchResults, 'maxSearchResults')));
596
+ applied.push('maxSearchResults');
597
+ }
598
+ return applied;
599
+ }
600
+ export function updateRuntimeConfig(updates) {
601
+ return applyRuntimeConfigUpdates(config, updates);
602
+ }
603
+ /**
604
+ * Public/supported operator config surface. Fields listed here are part of
605
+ * v2's stable contract: consumers can rely on their semantics and presence,
606
+ * and changes go through a documented deprecation cycle.
607
+ *
608
+ * This is a documentation type — it does not constrain threading. The runtime
609
+ * still carries a single `RuntimeConfig` object; this array tags the public
610
+ * subset so docs, tests, and future config-split work have a single source of
611
+ * truth. See also: https://docs.atomicmemory.ai/platform/consuming-core.
612
+ */
613
+ export const SUPPORTED_RUNTIME_CONFIG_FIELDS = [
614
+ // Infrastructure
615
+ 'databaseUrl', 'openaiApiKey', 'coreApiKey', 'storageKeyHmacSecret', 'port',
616
+ // Provider / model selection (startup config)
617
+ 'embeddingProvider', 'embeddingModel', 'embeddingDimensions',
618
+ 'embeddingApiUrl', 'embeddingApiKey',
619
+ 'voyageApiKey', 'voyageDocumentModel', 'voyageQueryModel',
620
+ 'llmProvider', 'llmModel', 'llmApiUrl', 'llmApiKey',
621
+ 'groqApiKey', 'anthropicApiKey', 'googleApiKey',
622
+ 'ollamaBaseUrl', 'vectorBackend', 'skipVectorIndexes', 'llmSeed',
623
+ 'crossEncoderModel', 'crossEncoderDtype',
624
+ // Operator-visible runtime
625
+ 'maxSearchResults', 'retrievalProfile', 'retrievalProfileSettings',
626
+ // Major feature toggles (surfaced in GET /v1/memories/health)
627
+ 'entityGraphEnabled', 'lessonsEnabled', 'agenticRetrievalEnabled',
628
+ 'iterativeRetrievalEnabled', 'hybridSearchEnabled', 'repairLoopEnabled',
629
+ 'crossEncoderEnabled', 'auditLoggingEnabled', 'adaptiveRetrievalEnabled',
630
+ 'consensusValidationEnabled', 'namespaceClassificationEnabled',
631
+ // Cost / cache ops
632
+ 'extractionCacheDir', 'costLogDir', 'costRunId', 'costLoggingEnabled',
633
+ // Dev/test-only mutation gate for PUT /v1/memories/config
634
+ // (see https://docs.atomicmemory.ai/platform/consuming-core)
635
+ 'runtimeConfigMutationEnabled',
636
+ ];
637
+ /**
638
+ * Internal policy config — experimental / tuning flags. Fields here may
639
+ * change semantics, defaults, or be removed without notice. Consumers should
640
+ * NOT rely on these in production. Promoted into the supported contract when
641
+ * a field's behavior stabilizes.
642
+ */
643
+ export const INTERNAL_POLICY_CONFIG_FIELDS = [
644
+ // Retrieval thresholds
645
+ 'similarityThreshold', 'audnCandidateThreshold', 'audnSafeReuseMinSimilarity',
646
+ 'crossAgentCandidateThreshold', 'clarificationConflictThreshold',
647
+ // Repair loop tuning
648
+ 'repairLoopMinSimilarity', 'repairSkipSimilarity',
649
+ 'repairDeltaThreshold', 'repairConfidenceFloor',
650
+ // Adaptive retrieval tuning
651
+ 'adaptiveSimpleLimit', 'adaptiveMediumLimit', 'adaptiveComplexLimit',
652
+ 'adaptiveMultiHopLimit', 'adaptiveAggregationLimit',
653
+ // MMR
654
+ 'mmrEnabled', 'mmrLambda',
655
+ // Link expansion
656
+ 'linkExpansionEnabled', 'linkExpansionMax',
657
+ 'linkSimilarityThreshold', 'linkExpansionBeforeMMR',
658
+ // Scoring weights
659
+ 'scoringWeightSimilarity', 'scoringWeightImportance', 'scoringWeightRecency',
660
+ // PPR
661
+ 'pprEnabled', 'pprDamping',
662
+ // Staging / tracing
663
+ 'stagedLoadingEnabled', 'retrievalTraceEnabled', 'ingestTraceDir', 'ingestTraceEnabled',
664
+ // Extraction internals
665
+ 'extractionCacheEnabled', 'embeddingCacheEnabled',
666
+ 'chunkedExtractionEnabled', 'chunkedExtractionFallbackEnabled',
667
+ 'chunkSizeTurns', 'chunkOverlapTurns',
668
+ 'consensusExtractionEnabled', 'consensusExtractionRuns',
669
+ 'observationDateExtractionEnabled', 'quotedEntityExtractionEnabled',
670
+ 'entropyGateEnabled', 'entropyGateThreshold', 'entropyGateAlpha',
671
+ // Affinity clustering
672
+ 'affinityClusteringThreshold', 'affinityClusteringMinSize',
673
+ 'affinityClusteringBeta', 'affinityClusteringTemporalLambda',
674
+ // Trust
675
+ 'trustScoringEnabled', 'trustScoreMinThreshold', 'trustPenaltyEnabled',
676
+ // Decay / caps
677
+ 'decayCycleEnabled', 'decayRetentionThreshold', 'decayMinAgeDays',
678
+ 'memoryCapEnabled', 'memoryCapMax', 'memoryCapWarnRatio',
679
+ // Entity tuning
680
+ 'entityResolutionThreshold', 'entitySearchMinSimilarity',
681
+ // Lesson tuning
682
+ 'lessonSimilarityThreshold',
683
+ // Consensus tuning
684
+ 'consensusMinMemories',
685
+ // Query expansion / augmentation
686
+ 'queryExpansionEnabled', 'queryExpansionMinSimilarity',
687
+ 'queryAugmentationEnabled', 'queryAugmentationMaxEntities',
688
+ 'queryAugmentationMinSimilarity',
689
+ // Rerank tuning
690
+ 'rerankSkipTopSimilarity', 'rerankSkipMinGap',
691
+ // Literal/list answer selection
692
+ 'literalListProtectionEnabled', 'literalListProtectionMaxProtected',
693
+ // Temporal query selection
694
+ 'temporalQueryConstraintEnabled', 'temporalQueryConstraintBoost',
695
+ // Fast AUDN
696
+ 'fastAudnEnabled', 'fastAudnDuplicateThreshold',
697
+ // Observation / deferred
698
+ 'observationNetworkEnabled', 'deferredAudnEnabled', 'deferredAudnBatchSize',
699
+ // Composite grouping
700
+ 'compositeGroupingEnabled', 'compositeMinClusterSize',
701
+ 'compositeMaxClusterSize', 'compositeSimilarityThreshold',
702
+ // Conflict handling
703
+ 'conflictAutoResolveMs',
704
+ // Typed Belief Calculus (Phase 1 scaffold; gates future TBC behavior)
705
+ 'tbcEnabled',
706
+ // Hierarchical Retrieval (T2; gates 5th RRF arm + summary table writes)
707
+ 'hierarchicalRetrievalEnabled',
708
+ // Sprint 3 EO experiment: topic-abstraction ingest layer + retrieval channel
709
+ 'topicAbstractionEnabled',
710
+ 'topicSearchEnabled',
711
+ // Sprint 3 v1: cross-encoder reranker on RRF top-N
712
+ 'rerankerEnabled',
713
+ 'rerankerTopN',
714
+ // Sprint 3 v1: Recap (cross-session synthesis) layer
715
+ 'recapLayerEnabled',
716
+ 'recapMinClusterSize',
717
+ 'recapSearchEnabled',
718
+ 'recapClusterPivot',
719
+ // Sprint 3 v1.1: counter-evidence retrieval via belief_edges graph
720
+ 'counterEvidenceEnabled',
721
+ // Sprint 3 v1.2: temporal-aware packaging — surface observed_at not created_at
722
+ 'packagingUseObservedAt',
723
+ // Sprint 3 v1.3: dual-date packaging — emit both created_at and observed_at
724
+ 'packagingDualDate',
725
+ // Sprint 3 v1.4: timeline channel — dedicated ## TIMELINE prompt section
726
+ 'timelineChannelEnabled',
727
+ // Sprint 4 iter 1: drop advisory-only memories from injection
728
+ 'answerOnlyRetrievalFilter',
729
+ // Sprint 4 iter 2: dedup near-duplicates by content fingerprint
730
+ 'retrievalDedupEnabled',
731
+ // Sprint 4 iter 3: BM25 keyword RRF weight (default 1.0; boost 1.5-2.0)
732
+ 'keywordRrfWeight',
733
+ // Sprint 4: Entity-Attribute Index (EAI) — (entity, attribute, value) lookups
734
+ 'entityAttributesEnabled',
735
+ 'entityAttributesTopK',
736
+ // Sprint 3 v1.5: user-profile channel — pinned `## USER PROFILE` block
737
+ 'userProfileChannelEnabled',
738
+ // Sprint 3 v1.6: episodes-as-separate-channel — `## EPISODES` block sourced
739
+ // from RecapStore candidates instead of RRF fan-in.
740
+ 'episodesChannelEnabled',
741
+ 'episodesChannelTopK',
742
+ // Sprint 3 v1.7: verifier-pass — second LLM call re-grounds candidate answer.
743
+ // Read by the AMB adapter via ATOMICMEMORY_VERIFIER_ENABLED; surfaced in
744
+ // core config so iteration env files can request it for symmetry.
745
+ 'verifierPassEnabled',
746
+ // BEAM-0.85 Phase 0 L1: answer-format alignment — prepends per-question-type
747
+ // FORMAT hint to the injection prompt to shape answer-LLM output structure.
748
+ 'answerFormatAlignmentEnabled',
749
+ // EO fix — data-driven event-chain detector: prepends ## EVENT_CHAIN channel
750
+ // when retrieved top-K contains 3+ memories for same entity across 3+ dates.
751
+ 'eventChainPackagingEnabled',
752
+ // BEAM-0.85 Phase 1: async reflection worker + retrieval channel.
753
+ 'reflectEnabled',
754
+ 'reflectRetrievalTopK',
755
+ 'reflectModel',
756
+ 'reflectMaxObservations',
757
+ 'reflectJobPollMs',
758
+ 'reflectDebounceMs',
759
+ // BEAM-0.85 Phase 2: specialist dispatcher gate (CR, TR, MSR, IE/KU).
760
+ 'phase2SpecialistsEnabled',
761
+ // Abstention-rescue: confidence prefix + iterative retrieval + Sonnet fallback.
762
+ 'abstentionRescueEnabled',
763
+ 'abstentionRescueRetrieveK',
764
+ 'abstentionRescueSonnetModel',
765
+ // BEAM v36: per-question-type adaptive confidence prefix (forced vs soft vs none).
766
+ 'confidencePrefixAdaptiveEnabled',
767
+ // BEAM v42: KU recency sort (NUMERIC_COUNT + KU-style queries → observed_at DESC).
768
+ 'kuRecencySortEnabled',
769
+ // BEAM v39-multihop: MSR cross-conversation aggregator (retrieval-side channel).
770
+ 'msrAggregatorEnabled',
771
+ // BEAM-0.85: always-on per-entity ENTITY_CARD channel (Honcho parity).
772
+ 'entityCardEnabled',
773
+ 'entityCardMaxPerSession',
774
+ 'entityCardMinObservations',
775
+ // BEAM CR fix (2026-05-12): AUDN bilateral preservation for contradictions.
776
+ 'contradictionPreservationEnabled',
777
+ 'contradictionSurfacingEnabled',
778
+ // BEAM v38 (2026-05-12): temporal state layer (write/read for KU).
779
+ 'temporalStateEnabled',
780
+ // Document pipeline (Phases 1 + 3). The raw-storage knobs are
781
+ // operator-visible at startup and intentionally NOT mutable at
782
+ // runtime — moving the storage backend mid-process would orphan
783
+ // already-persisted blobs.
784
+ 'rawStorageMode',
785
+ 'rawStorageProvider',
786
+ 'rawStoragePrefix',
787
+ 'rawStorageLocalFsRoot',
788
+ 'rawStorageS3Bucket',
789
+ 'rawStorageS3Region',
790
+ 'rawStorageS3Endpoint',
791
+ 'rawStorageS3AccessKeyId',
792
+ 'rawStorageS3SecretAccessKey',
793
+ 'rawUploadMaxBytes',
794
+ // Filecoin raw storage: content codec + deployment env. Same
795
+ // operator-visible-at-startup, not-runtime-mutable contract as the
796
+ // raw-storage block above.
797
+ 'rawContentCodec',
798
+ 'rawContentCodecKeys',
799
+ 'rawContentCodecActiveKeyId',
800
+ 'rawStorageDeploymentEnv',
801
+ // Synapse-shaped Filecoin provider config. Single grouped field on
802
+ // `RuntimeConfig`; the underlying env var surface is
803
+ // `RAW_STORAGE_FILECOIN_*` and the parser lives in
804
+ // `src/storage/providers/filecoin/config.ts`.
805
+ 'filecoinProvider',
806
+ 'rawStorageLegacyProviders',
807
+ 'rawStoragePointerUriSchemes',
808
+ ];